# Store height and width of the image height, width = image.shape[:2]
quarter_height, quarter_width = height/4, width/4
# | 1 0 Tx | Tx Represents the shift along the x-axis (horizonal) # T = | 0 1 Ty | Ty Represents the shift along the y-axis (vertical)
# T is our translation matrix T = np.float32([[1, 0, quarter_width], [0, 1,quarter_height]])
# We use warpAffine to transform the image using the matrix, T img_translation = cv2.warpAffine(image, T, (width, height)) cv2.imshow('Translation', img_translation) cv2.waitKey() cv2.destroyAllWindows()
# Create a matrix of ones, then multiply it by a scaler of 100 # This gives a matrix with same dimesions of our image with all values being 100 M = np.ones(image.shape, dtype = "uint8") * 75 # M = np.ones(image.shape, dtype = "uint8") * 175 # ^ Try this code!
# We use this to add this matrix M, to our image # Notice the increase in brightness added = cv2.add(image, M) cv2.imshow("Added", added)
# Likewise we can also subtract # Notice the decrease in brightness subtracted = cv2.subtract(image, M) cv2.imshow("Subtracted", subtracted)
cv2.waitKey(0) cv2.destroyAllWindows()
1 2
M = np.ones(image.shape, dtype = "uint8") * 75 print(M)
# If you're wondering why only two dimensions, well this is a grayscale image, # if we doing a colored image, we'd use # rectangle = np.zeros((300, 300, 3),np.uint8)
# Making a sqare square = np.zeros((300, 300), np.uint8) cv2.rectangle(square, (50, 50), (250, 250), 255, -2) cv2.imshow("Square", square) cv2.waitKey(0)
# Shows only where they intersect And = cv2.bitwise_and(square, ellipse) cv2.imshow("AND", And) cv2.waitKey(0)
#^ Press any key to continue...
# Shows where either square or ellipse is bitwiseOr = cv2.bitwise_or(square, ellipse) cv2.imshow("OR", bitwiseOr) cv2.waitKey(0)
#^ Press any key to continue...
# Shows where either exist by itself bitwiseXor = cv2.bitwise_xor(square, ellipse) cv2.imshow("XOR", bitwiseXor) cv2.waitKey(0)
#^ Press any key to continue...
# Shows everything that isn't part of the square bitwiseNot_sq = cv2.bitwise_not(square) cv2.imshow("NOT - square", bitwiseNot_sq) cv2.waitKey(0)
#^ Press any key to continue...
### Notice the last operation inverts the image totally
cv2.destroyAllWindows()
Blurring and Sharpening
Convolution
What is Convolution?
A Convolution is a mathematical operation performed on two functions producing a third function which is typically a modified version of one of the original functions.
In Computer Vision we use kernel’s to specify the size over which we run our manipulating function over our image.
OutputImage=Image⊛FunctionKernelSize
Why mention Convolution?
Convolution are found in many applications in science, engineering and mathematics.
# We use the cv2.fitler2D to conovlve the kernal with an image blurred = cv2.filter2D(image, -1, kernel_3x3) cv2.imshow('3x3 Kernel Blurring', blurred) cv2.waitKey(0)
# Averaging done by convolving the image with a normalized box filter. # This takes the pixels under the box and replaces the central element # Box size needs to odd and positive blur = cv2.blur(image, (3,3)) cv2.imshow('Averaging', blur) cv2.waitKey(0)
# Takes median of all the pixels under kernel area and central # element is replaced with this median value median = cv2.medianBlur(image, 5) cv2.imshow('Median Blurring', median) cv2.waitKey(0)
# Bilateral is very effective in noise removal while keeping edges sharp bilateral = cv2.bilateralFilter(image, 9, 75, 75) cv2.imshow('Bilateral Blurring', bilateral) cv2.waitKey(0) cv2.destroyAllWindows()
Image De-noising
Used to get the best optimized noise level. Cellphone cameras and digital cameras will use those algorithms.
cv2.fastNlMeansDenoising() - works with a single grayscale images
cv2.fastNlMeansDenoisingColored() - works with a color image.
cv2.fastNlMeansDenoisingMulti() - works with image sequence captured in short period of time (grayscale images)
cv2.fastNlMeansDenoisingColoredMulti() - same as above, but for color images.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
import numpy as np import cv2
image = cv2.imread('images/elephant.jpg')
# Parameters, after None are - the filter strength 'h' (5-10 is a good range) # Next is hForColorComponents, set as same value as h again # dst = cv2.fastNlMeansDenoisingColored(image, None, 6, 6, 7, 21)
cv2.imshow('Fast Means Denoising', dst) cv2.waitKey(0)
cv2.destroyAllWindows()
Sharpening
What is Sharpening?
Sharpening is the opposite of blurring, it stengthes or emphasizing edges in an image.
Code Implementation
By altering our kernels we can implement sharpening, which has the effects of in strengthening or emphasizing edges in an image.
# Create our shapening kernel, we don't normalize since the # the values in the matrix sum to 1 kernel_sharpening = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
# applying different kernels to the input image sharpened = cv2.filter2D(image, -1, kernel_sharpening)
# Values below 127 go to 255 and values above 127 go to 0 (reverse of above) ret,thresh2 = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY_INV) cv2.imshow('2 Threshold Binary Inverse', thresh2)
# Values above 127 are truncated (held) at 127 (the 255 argument is unused) ret,thresh3 = cv2.threshold(image, 127, 255, cv2.THRESH_TRUNC) cv2.imshow('3 THRESH TRUNC', thresh3)
# Values below 127 go to 0, above 127 are unchanged ret,thresh4 = cv2.threshold(image, 127, 255, cv2.THRESH_TOZERO) cv2.imshow('4 THRESH TOZERO', thresh4)
# Resever of above, below 127 is unchanged, above 127 goes to 0 ret,thresh5 = cv2.threshold(image, 127, 255, cv2.THRESH_TOZERO_INV) cv2.imshow('5 THRESH TOZERO INV', thresh5) cv2.waitKey(0) cv2.destroyAllWindows()
## Then, we need to provide two values: threshold1 and threshold2. Any gradient value larger than threshold2 # is considered to be an edge. Any value below threshold1 is considered not to be an edge. #Values in between threshold1 and threshold2 are either classified as edges or non-edges based on how their #intensities are “connected”. In this case, any gradient values below 60 are considered non-edges #whereas any values above 120 are considered edges.
# Canny Edge Detection uses gradient values as thresholds # The first threshold gradient canny = cv2.Canny(image, 50, 120) cv2.imshow('Canny', canny) cv2.waitKey(0)
cv2.destroyAllWindows()
Mapping of points between images
Non Affine / Projective / Perspective Transformations
import cv2 import numpy as np import matplotlib.pyplot as plt
image = cv2.imread('images/scan.jpg')
cv2.imshow('Original', image) cv2.waitKey(0)
# Cordinates of the 4 corners of the original image points_A = np.float32([[320,15], [700,215], [85,610], [530,780]])
# Cordinates of the 4 corners of the desired output # We use a ratio of an A4 Paper 1 : 1.41 points_B = np.float32([[0,0], [420,0], [0,594], [420,594]]) # Use the two sets of four points to compute # the Perspective Transformation matrix, M M = cv2.getPerspectiveTransform(points_A, points_B) warped = cv2.warpPerspective(image, M, (420,594)) cv2.imshow('warpPerspective', warped) cv2.waitKey(0) cv2.destroyAllWindows()
Affine Transform
In affine transforms you only need 3 coordinates to obtain the correct transform.
# Cordinates of the 4 corners of the original image points_A = np.float32([[320,15], [700,215], [85,610]])
# Cordinates of the 4 corners of the desired output # We use a ratio of an A4 Paper 1 : 1.41 points_B = np.float32([[0,0], [420,0], [0,594]]) # Use the two sets of four points to compute # the Perspective Transformation matrix, M M = cv2.getAffineTransform(points_A, points_B)
warped = cv2.warpAffine(image, M, (cols, rows)) cv2.imshow('warpPerspective', warped) cv2.waitKey(0) cv2.destroyAllWindows()