Convolution is the same mathematical operation encountered in three different contexts of image processing: Gaussian noise removal, template matching and edge detection. Convolution is defined as
$$G[i,j] = \sum_{u=-k}^k\sum_{v=-k}^k H[u,v]F[i-u,j-v]$$Flipping the signs of $u$ and $v$, we have the formula for correlation:
$$G[i,j] = \sum_{u=-k}^k\sum_{v=-k}^k H[u,v]F[i+u,j+v]$$Gaussian noise removal¶
The expected value of a Gaussian distribution of mean 0 is 0. Therefore, if the nearby pixels have similar values and the noise is Gaussian, their average would cancel out the noise.
import numpy as np
from matplotlib import pyplot as plt
import cv2
plt.figure(figsize = (12, 20))
bicycle = cv2.cvtColor(cv2.imread('bicycle.png'), cv2.COLOR_RGB2GRAY)
plt.subplot(131), plt.imshow(bicycle, cmap='gray')
bicycle = bicycle + 30*np.random.standard_normal(bicycle.shape)
plt.subplot(132), plt.imshow(bicycle, cmap='gray')
bicycle = cv2.GaussianBlur(bicycle, (7,7), 30)
plt.subplot(133), plt.imshow(bicycle, cmap='gray')
plt.show()
Template matching¶
By Holder inequality, when $\sum x_i^2=1$ and $\sum y_i^2=1$, the sum of products $\sum x_i y_i$ achieves the maximum when $x_i = y_i$. Therefore, the patch which convolves with the template and achieves the maximum value is most likely to the match.
.
import numpy as np
from matplotlib import pyplot as plt
import cv2
plt.figure(figsize = (12, 20))
bicycle = cv2.imread('bicycle.png')
glyph = bicycle[150:350, 100:250]
plt.subplot(1,9,(1,3)), plt.imshow(bicycle, cmap='gray')
plt.subplot(1,9,5), plt.imshow(glyph, cmap='gray')
matching = cv2.matchTemplate(bicycle, glyph, cv2.TM_CCORR_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(matching)
top_left = max_loc
bottom_right = (max_loc[0] + glyph.shape[1], max_loc[1] + glyph.shape[0])
cv2.rectangle(bicycle, top_left, bottom_right, 255, 3)
plt.subplot(1,9,(7,9)), plt.imshow(bicycle, cmap='gray')
plt.show()
Edge detection¶
The derivative of a function at a point measures how quickly that function changes at that point. This notion can be used to detect edges, which are the boundary between different regions.
import numpy as np
from matplotlib import pyplot as plt
import cv2
plt.figure(figsize = (16,8))
image = cv2.cvtColor(cv2.imread('images/bicycle.png'), cv2.COLOR_RGB2GRAY)
blur_image = cv2.GaussianBlur(image, (5,5), 5)
plt.subplot(231), plt.imshow(image, cmap='gray')
plt.subplot(234), plt.imshow(blur_image, cmap='gray')
# Method 1 - Sobel
sobel_x = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]])
sobel_y = np.array([[-1, -1, -1], [0, 0, 0], [1, 1, 1]])
plt.subplot(232), plt.imshow(cv2.filter2D(blur_image, -1, sobel_x), cmap='gray')
plt.subplot(235), plt.imshow(cv2.filter2D(blur_image, -1, sobel_y), cmap='gray')
# Method 2 - Laplacian
plt.subplot(233), plt.imshow(cv2.Laplacian(blur_image, cv2.CV_32F, ksize=3), cmap='gray')
# Method 3 - Canny
plt.subplot(236), plt.imshow(cv2.Canny(blur_image, 10, 50), cmap='gray')
plt.show()