Image Processing using OpenCV.
- Tung San
- Jun 27, 2022
- 2 min read
import matplotlib.pyplot as plt
%matplotlib inline
import cv2
import numpy as np
def printm(X):
print(f"{X}, {X.shape}\n")
Image Processing in view of matrix
Define a matrix
F = np.mat("0 2 3 5; 2 3 1 0; 0 0 1 1; 2 2 3 0")
printm(F)

Blurring
F_pad = cv2.copyMakeBorder(F, 1, 1, 1, 1, cv2.BORDER_CONSTANT, (0,0,0))
printm(F_pad)

Blurring using cv2.blur
G_pad=cv2.blur(F_pad, (3,3))
G = G_pad[1:5,1:5]
printm(G)

Blurring using convolution
K=np.ones((3,3))*1/9
print("Kernel K:")
printm(np.round(K,2))
xsize = F_pad.shape[0]
ysize = F_pad.shape[1]
index = [(x,y) for x in range(1, xsize-1) for y in range(1, ysize-1)]
result=[]
for i,j in index:
X = F_pad[i-1:(i+1)+1, j-1:(j+1)+1]
convolute = np.multiply(X, K).sum()
result.append(convolute)
M = np.mat(result).reshape(xsize-2, ysize-2)
print("Result M:")
printm(np.round(M,2))

Display images
plt.figure(figsize = (5,5))
image = cv2.imread('cat.jpg')
print(image.shape)
plt.imshow(image)
plt.show()

OpenCV represents the images in BGR, not RGB. Thus it shows weird picture.
plt.figure(figsize = (5,5))
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
plt.imshow(image)
plt.show()

Use cv2.cvtColor() and cv2.COLOR_BGR2RGB to convert colour scheme.
plt.figure(figsize = (5,5))
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
plt.imshow(image,cmap ='gray')
plt.show()

Use cv2.cvtColor() and cv2.COLOR_BGR2GRAY.
Image Gradient
plt.figure(figsize = (10,10))
plt.subplot(1,2,1)
gradient_x1 = cv2.Sobel(image, cv2.CV_16S, dx=1, dy=0, ksize=9)
plt.imshow(gradient_x1,cmap ='gray')
plt.subplot(1,2,2)
gradient_y1 = cv2.Sobel(image, cv2.CV_16S, dx=0, dy=1, ksize=9)
plt.imshow(gradient_y1,cmap ='gray')
plt.show()

Use Sobel operator to approximate derivatives in x and y directions. https://docs.opencv.org/3.4/d2/d2c/tutorial_sobel_derivatives.html
Fourier Transform
Original image.
plt.imshow(image, cmap='gray')

plt.figure(figsize = (5,5))
F = np.fft.fft2(image)
F = np.abs(F)
F = np.fft.fftshift(F)
F = 100*np.log(F)
plt.imshow(F, cmap='gray')
The image in frequency domain

Inverse Fourier Transform. Observe that the transformation has No loss of information.
plt.figure(figsize = (5,5))
F = np.fft.fft2(image)
f = np.fft.ifft2(F)
f = np.abs(f)
plt.imshow(f, cmap='gray')
plt.show()

Resize by Interpolation
plt.figure(figsize=(5,5))
R0 = image
resize = (2*R0.shape[0], 2*R0.shape[1])
R1 = cv2.resize(R0, resize, interpolation=cv2.INTER_LINEAR)
plt.imshow(R1,cmap ='gray')
plt.show()
print(R0.shape)
print(R1.shape)
cv2.resize() OpenCV uses numpy and Numpy array assumes (height, width). OpenCV functions uses (width, height).

Linear Interpolation. Use cv2.INTER_LINEAR.
plt.figure(figsize=(5,5))
resize = (2*R0.shape[1], 2*R0.shape[0])
R2 = cv2.resize(R0, resize, interpolation=cv2.INTER_LINEAR)
plt.imshow(R2,cmap ='gray')
plt.show()
print(R0.shape)
print(R2.shape)

Non-linear Interpolation. Use cv2.INTER_LINEAR.
plt.figure(figsize=(5,5))
resize = (4*R0.shape[1], 4*R0.shape[0])
R2 = cv2.resize(R0, resize, interpolation=cv2.INTER_CUBIC)
plt.imshow(R2,cmap ='gray')
plt.show()
print(R0.shape)
print(R2.shape)

Image Pyramid
Making Gaussian Pyramid. cv2.pyrDown().
plt.figure(figsize=(15,15))
up1 = cv2.pyrDown(image)
up2 = cv2.pyrDown(up1)
up3 = cv2.pyrDown(up2)
up4 = cv2.pyrDown(up3)
plt.subplot(2,2,1)
plt.imshow(up1,cmap ='gray')
plt.subplot(2,2,2)
plt.imshow(up2,cmap ='gray')
plt.subplot(2,2,3)
plt.imshow(up3,cmap ='gray')
plt.subplot(2,2,4)
plt.imshow(up4,cmap ='gray')
plt.show()

Image loss in down sampling. Build Laplacian Pyramids for filling up the gap. cv2.pyrUp()
Lapa3_to_2 = up2 - cv2.pyrUp(up3)
Lapa2_to_1 = up1 - cv2.pyrUp(up2)
Lapa1_to_0 = image - cv2.pyrUp(up1)
plt.figure(figsize=(15,15))
plt.subplot(2,2,1)
plt.imshow(Lapa3_to_2,cmap ='gray')
plt.subplot(2,2,2)
plt.imshow(Lapa2_to_1,cmap ='gray')
plt.subplot(2,2,3)
plt.imshow(Lapa1_to_0,cmap ='gray')
plt.show()

Key-point detection
image = cv2.imread('cat.jpg')
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
shape = (int(image.shape[1]/4), int(image.shape[0]/4))
image = cv2.resize(image, shape)
image2 = cv2.imread('cat2.jpg')
image2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)
shape2 = (int(image2.shape[1]/4), int(image2.shape[0]/4))
image2 = cv2.resize(image2, shape)
plt.figure(figsize = (15,15))
plt.subplot(1,2,1)
plt.imshow(image, cmap='gray')
plt.subplot(1,2,2)
plt.imshow(image2, cmap ='gray')
plt.show()
Drawing key-points. cv2.SIFT_create(), cv2.drawKeypoints().
sift = cv2.SIFT_create()
plt.figure(figsize=(15,15))
image_keypoints = sift.detect(image,None)
image_drawKeypoints = cv2.drawKeypoints(image, image_keypoints, np.array([]), flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
plt.subplot(1,2,1)
plt.imshow(image_drawKeypoints, cmap = 'gray')
image2_keypoints = sift.detect(image2,None)
image2_drawKeypoints = cv2.drawKeypoints(image2, image2_keypoints, np.array([]), flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
plt.subplot(1,2,2)
plt.imshow(image2_drawKeypoints, cmap = 'gray')
plt.show()

Matching key-points. sift.detectAndCompute(), cv2.BFMatcher(), cv2.drawMatchesKnn().
keypoints1, descriptors1 = sift.detectAndCompute(image,None)
keypoints2, descriptors2 = sift.detectAndCompute(image2,None)
bf_matcher = cv2.BFMatcher()
matches = bf_matcher.knnMatch(descriptors1, descriptors2, k=2)
good_matches = []
for m,n in matches:
if m.distance < 0.9*n.distance:
good_matches.append([m])
print("len(good_matches):", len(good_matches))
draw_params = dict(matchColor = (0,200,0),
singlePointColor = (200,0,0),
flags = cv2.DrawMatchesFlags_DEFAULT)
# cv.drawMatchesKnn expects list of lists as matches.
img = cv2.drawMatchesKnn(image, keypoints1, image2, keypoints2, good_matches, None,
**draw_params)
plt.figure(figsize=(10,10))
plt.imshow(img)
plt.show()

Comments