123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575 |
- """
- Functions which can be used to extract information from image or reduce it
- """
- # main imports
- import os
- import random
- import numpy as np
- # image processing imports
- from numpy.linalg import svd
- from scipy import misc
- from sklearn import preprocessing
- from skimage import io, color
- import cv2
- from PIL import Image
- # ipfml imports
- from ipfml.processing import compression
- def get_LAB(image):
- """Transforms RGB Image into Lab
- Args:
- image: image to convert
- Returns:
- Lab information
- Usage:
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> Lab = transform.get_LAB(img)
- >>> Lab.shape
- (200, 200, 3)
- """
- return color.rgb2lab(image)
- def get_LAB_L(image):
- """Transforms RGB Image into Lab and returns L
- Args:
- image: image to convert
- Returns:
- The L chanel from Lab information
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> L = transform.get_LAB_L(img)
- >>> L.shape
- (200, 200)
- """
- lab = get_LAB(image)
- return lab[:, :, 0]
- def get_LAB_a(image):
- """Transforms RGB Image into LAB and returns a
- Args:
- image: image to convert
- Returns:
- The a chanel from Lab information
- Usage:
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> a = transform.get_LAB_a(img)
- >>> a.shape
- (200, 200)
- """
- lab = get_LAB(image)
- return lab[:, :, 1]
- def get_LAB_b(image):
- """Transforms RGB Image into LAB and returns b
- Args:
- image: image to convert
- Returns:
- The b chanel from Lab information
- Usage :
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> b = transform.get_LAB_b(img)
- >>> b.shape
- (200, 200)
- """
- lab = get_LAB(image)
- return lab[:, :, 2]
- def get_XYZ(image):
- """Transforms RGB Image into XYZ
- Args:
- image: image to convert
- Returns:
- XYZ information obtained from transformation
- Usage:
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> transform.get_XYZ(img).shape
- (200, 200, 3)
- """
- return color.rgb2xyz(image)
- def get_XYZ_X(image):
- """Transforms RGB Image into XYZ and returns X
- Args:
- image: image to convert
- Returns:
- The X chanel from XYZ information
- Usage:
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> x = transform.get_XYZ_X(img)
- >>> x.shape
- (200, 200)
- """
- xyz = color.rgb2xyz(image)
- return xyz[:, :, 0]
- def get_XYZ_Y(image):
- """Transforms RGB Image into XYZ and returns Y
- Args:
- image: image to convert
- Returns:
- The Y chanel from XYZ information
- Usage:
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> y = transform.get_XYZ_Y(img)
- >>> y.shape
- (200, 200)
- """
- xyz = color.rgb2xyz(image)
- return xyz[:, :, 1]
- def get_XYZ_Z(image):
- """Transforms RGB Image into XYZ and returns Z
- Args:
- image: image to convert
- Returns:
- The Z chanel from XYZ information
- Raises:
- ValueError: If `nb_bits` has unexpected value. `nb_bits` needs to be in interval [1, 8].
- Usage:
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> z = transform.get_XYZ_Z(img)
- >>> z.shape
- (200, 200)
- """
- xyz = color.rgb2xyz(image)
- return xyz[:, :, 2]
- def get_low_bits_img(image, nb_bits=4):
- """Returns Image or Numpy array with data information reduced using only low bits
- Args:
- image: image to convert
- nb_bits: optional parameter which indicates the number of bits to keep
- Returns:
- Numpy array with reduced values
- Usage:
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> low_bits_img = transform.get_low_bits_img(img, 5)
- >>> low_bits_img.shape
- (200, 200, 3)
- """
- if nb_bits <= 0:
- raise ValueError(
- "unexpected value of number of bits to keep. @nb_bits needs to be positive and greater than 0."
- )
- if nb_bits > 8:
- raise ValueError(
- "Unexpected value of number of bits to keep. @nb_bits needs to be in interval [1, 8]."
- )
- img_arr = np.array(image)
- bits_values = sum([pow(2, i - 1) for i in range(1, nb_bits + 1)])
- return img_arr & bits_values
- def get_bits_img(image, interval):
- """Returns only bits specified into the interval
- Args:
- image: image to convert using this interval of bits value to keep
- interval: (begin, end) of bits values
- Returns:
- Numpy array with reduced values
- Raises:
- ValueError: If min value from interval is not >= 1.
- ValueError: If max value from interval is not <= 8.
- ValueError: If min value from interval >= max value.
- Usage:
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> bits_img = transform.get_bits_img(img, (2, 5))
- >>> bits_img.shape
- (200, 200, 3)
- """
- img_arr = np.array(image)
- begin, end = interval
- if begin < 1:
- raise ValueError(
- "Unexpected value of interval. Interval min value needs to be >= 1."
- )
- if end > 8:
- raise ValueError(
- "Unexpected value of interval. Interval min value needs to be <= 8."
- )
- if begin >= end:
- raise ValueError("Unexpected interval values order.")
- bits_values = sum([pow(2, i - 1) for i in range(begin, end + 1)])
- return img_arr & bits_values
- def gray_to_mscn(image):
- """Convert Grayscale Image into Mean Subtracted Contrast Normalized (MSCN)
- Args:
- image: grayscale image
- Returns:
- MSCN matrix obtained from transformation
- Usage:
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> img = transform.get_LAB_L(img)
- >>> img_mscn = transform.gray_to_mscn(img)
- >>> img_mscn.shape
- (200, 200)
- """
- s = 7 / 6
- blurred = cv2.GaussianBlur(image, (7, 7),
- s) # apply gaussian blur to the image
- blurred_sq = blurred * blurred
- sigma = cv2.GaussianBlur(image * image, (7, 7), s)
- sigma = abs(sigma - blurred_sq)**0.5
- sigma = sigma + 1.0 / 255 # avoid DivideByZero Exception
- mscn = (image - blurred) / sigma # MSCN(i, j) image
- return mscn
- def rgb_to_mscn(image):
- """Convert RGB Image into Mean Subtracted Contrast Normalized (MSCN)
- Args:
- image: 3D RGB image Numpy array or PIL RGB image
- Returns:
- 2D Numpy array with MSCN information
- Example:
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> img_mscn = transform.rgb_to_mscn(img)
- >>> img_mscn.shape
- (200, 200)
- """
- # check if PIL image or not
- img_arr = np.array(image)
- # convert rgb image to gray
- im = np.array(color.rgb2gray(img_arr) * 255, 'uint8')
- return gray_to_mscn(im)
- def get_mscn_coefficients(image):
- """Compute the Mean Substracted Constrast Normalized coefficients of an image
- Args:
- image: PIL Image, Numpy array or path of image
- Returns:
- MSCN coefficients
- Raises:
- FileNotFoundError: If `image` is set as str path and image was not found
- ValueError: If `image` numpy shape are not correct
- Example:
- >>> from PIL import Image
- >>> import numpy as np
- >>> from ipfml.processing import transform
- >>> image_values = Image.open('./images/test_img.png')
- >>> mscn_coefficients = transform.get_mscn_coefficients(image_values)
- >>> mscn_coefficients.shape
- (200, 200)
- """
- if isinstance(image, str):
- if os.path.exists(image):
- # open image directly as grey level image
- imdist = cv2.imread(image, 0)
- else:
- raise FileNotFoundError('Image not found in your system')
- elif isinstance(image, np.ndarray):
- # convert if necessary to grey level numpy array
- if image.ndim == 2:
- imdist = image
- if image.ndim == 3:
- imdist = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
- else:
- raise ValueError('Incorrect image shape')
- else:
- # if PIL Image
- image = np.asarray(image)
- if image.ndim == 2:
- imdist = image
- if image.ndim == 3:
- imdist = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
- else:
- raise ValueError('Incorrect image shape')
- imdist = imdist.astype(np.float64)
- imdist = imdist / 255.0
- # calculating MSCN coefficients
- mu = cv2.GaussianBlur(
- imdist, (7, 7), 7 / 6, borderType=cv2.BORDER_CONSTANT)
- mu_sq = mu * mu
- sigma = cv2.GaussianBlur(
- imdist * imdist, (7, 7), 7 / 6, borderType=cv2.BORDER_CONSTANT)
- sigma = np.sqrt(abs((sigma - mu_sq)))
- structdis = (imdist - mu) / (sigma + 1)
- return structdis
- def get_LAB_L_SVD(image):
- """Returns Singular values from LAB L Image information
- Args:
- image: PIL Image or Numpy array
- Returns:
- U, s, V information obtained from SVD compression using Lab
- Example:
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> U, s, V = transform.get_LAB_L_SVD(img)
- >>> U.shape
- (200, 200)
- >>> len(s)
- 200
- >>> V.shape
- (200, 200)
- """
- L = get_LAB_L(image)
- return compression.get_SVD(L)
- def get_LAB_L_SVD_s(image):
- """Returns s (Singular values) SVD from L of LAB Image information
- Args:
- image: PIL Image or Numpy array
- Returns:
- vector of singular values
- Example:
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> s = transform.get_LAB_L_SVD_s(img)
- >>> len(s)
- 200
- """
- L = get_LAB_L(image)
- return compression.get_SVD_s(L)
- def get_LAB_L_SVD_U(image):
- """Returns U SVD from L of LAB Image information
- Args:
- image: PIL Image or Numpy array
- Returns:
- U matrix of SVD compression
- Example:
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> U = transform.get_LAB_L_SVD_U(img)
- >>> U.shape
- (200, 200)
- """
- L = get_LAB_L(image)
- return compression.get_SVD_U(L)
- def get_LAB_L_SVD_V(image):
- """Returns V SVD from L of LAB Image information
- Args:
- image: PIL Image or Numpy array
- Returns:
- V matrix of SVD compression
- Example:
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> V = transform.get_LAB_L_SVD_V(img)
- >>> V.shape
- (200, 200)
- """
- L = get_LAB_L(image)
- return compression.get_SVD_V(L)
- def rgb_to_grey_low_bits(image, nb_bits=4):
- """Convert RGB Image into grey image using only 4 low bits values
- Args:
- image: 3D RGB image Numpy array or PIL RGB image
- nb_bits: optional parameter which indicates the number of bits to keep (default 4)
- Returns:
- 2D Numpy array with low bits information kept
- Example:
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> low_bits_grey_img = transform.rgb_to_grey_low_bits(img, 5)
- >>> low_bits_grey_img.shape
- (200, 200)
- """
- img_arr = np.array(image)
- grey_block = np.array(color.rgb2gray(img_arr) * 255, 'uint8')
- return get_low_bits_img(grey_block, nb_bits)
- def rgb_to_LAB_L_low_bits(image, nb_bits=4):
- """Convert RGB Image into Lab L channel image using only 4 low bits values
- Args:
- image: 3D RGB image Numpy array or PIL RGB image
- nb_bits: optional parameter which indicates the number of bits to keep (default 4)
- Returns:
- 2D Numpy array with low bits information kept
- Example:
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> low_bits_Lab_l_img = transform.rgb_to_LAB_L_low_bits(img, 5)
- >>> low_bits_Lab_l_img.shape
- (200, 200)
- """
- L_block = np.asarray(get_LAB_L(image), 'uint8')
- return get_low_bits_img(L_block, nb_bits)
- def rgb_to_LAB_L_bits(image, interval):
- """Returns only bits from LAB L canal specified into the interval
- Args:
- image: image to convert using this interval of bits value to keep
- interval: (begin, end) of bits values
- Returns:
- 2D Numpy array with reduced values
- >>> from PIL import Image
- >>> from ipfml.processing import transform
- >>> img = Image.open('./images/test_img.png')
- >>> bits_Lab_l_img = transform.rgb_to_LAB_L_bits(img, (2, 6))
- >>> bits_Lab_l_img.shape
- (200, 200)
- """
- L_block = np.asarray(get_LAB_L(image), 'uint8')
- return get_bits_img(L_block, interval)
|