I will write that I investigated the preprocessing method of images for machine learning. The content is half-finished, but I think I will add more in the future.
Windows10 python 3.6 opencv-python 4.1.2.30
opencv documentation http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html
I will make an appropriate gradation image and binarize it
# make gray scale picture
im_gray = np.array([np.arange(0, 256, 2) for k in range(100)])
im_gray = im_gray.astype('uint8')
print(im_gray.shape)
# apply threshold
ret, thresh1 = cv2.threshold(im_gray,127,255,cv2.THRESH_BINARY)
# show picture
plt.figure(figsize=(7, 6))
ax = plt.subplot(1, 2, 1)
ax.imshow(im_gray, 'gray')
ax.set_xticks([])
ax.set_yticks([])
ax.set_title('ORIGINAL')
ax = plt.subplot(1, 2, 2)
ax.imshow(thresh1, 'gray')
ax.set_xticks([])
ax.set_yticks([])
ax.set_title('BINARY')
plt.show()
Binarize using Otsu's method
# make gray scale picture
im_gray = np.array([np.arange(0, 256, 2) for k in range(100)])
im_gray = im_gray.astype('uint8')
print(im_gray.shape)
# global thresholding
ret1,th1 = cv2.threshold(im_gray,127,255,cv2.THRESH_BINARY)
# Otsu's thresholding
ret2,th2 = cv2.threshold(im_gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# show picture
plt.figure(figsize=(7, 6))
ax = plt.subplot(1, 2, 1)
ax.imshow(im_gray, 'gray')
ax.set_xticks([])
ax.set_yticks([])
ax.set_title('ORIGINAL')
ax = plt.subplot(1, 2, 2)
ax.imshow(thresh1, 'gray')
ax.set_xticks([])
ax.set_yticks([])
ax.set_title('OTSU')
plt.show()
It is used when there is a gradation of brightness such as a photographic image and the entire image cannot be binarized with one threshold value. http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('../input/dave.jpg',0)
img = cv2.medianBlur(img,5)
ret,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
th2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
cv2.THRESH_BINARY,11,2)
th3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
cv2.THRESH_BINARY,11,2)
titles = ['Original Image', 'Global Thresholding (v = 127)',
'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
images = [img, th1, th2, th3]
plt.figure(figsize=(6.5, 6))
for i in range(4):
plt.subplot(2,2,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
There are various threshold Types other than the frequently used binarization.
# make gray scale picture
im_gray = np.array([np.arange(0, 256, 2) for k in range(100)])
im_gray = im_gray.astype('uint8')
print(im_gray.shape)
# apply threshold
ret,thresh1 = cv2.threshold(im_gray,127,255,cv2.THRESH_BINARY)
ret,thresh2 = cv2.threshold(im_gray,127,255,cv2.THRESH_BINARY_INV)
ret,thresh3 = cv2.threshold(im_gray,127,255,cv2.THRESH_TRUNC)
ret,thresh4 = cv2.threshold(im_gray,127,255,cv2.THRESH_TOZERO)
ret,thresh5 = cv2.threshold(im_gray,127,255,cv2.THRESH_TOZERO_INV)
# show result
titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images = [im_gray, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(6):
plt.subplot(2,3,i+1)
plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
From here, read an appropriate image file and use it. You can read the image as numpy.array with cv2.imread (). I use cv2.imshow () or plt.imshow () to display the image, but cv2.imshow () doesn't seem to work with jupyter notebook, so I will display it with plt.imshow (). However, while opencv traditionally reads the value in BGR, plt.imshow () displays it as RGB, so after swapping R and B with cv2.cvtColor (src, cv2.COLOR_BGR2RGB) I will display it.
python
import cv2
import matplotlib.pyplot as plt
im = cv2.imread('../input/opencv.png')
plt.imshow(cv2.cvtColor(im, cv2.COLOR_BGR2RGB))
plt.xticks([])
plt.yticks([])
plt.show()
This time I will do it with this image
opencv documentation http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_filtering/py_filtering.html
A filter that blurs the image. size is the vertical and horizontal size, and sigma is the vertical and horizontal standard deviation. You can also specify sigma vertically and horizontally, but if omitted, the same standard deviation will be used for both vertically and horizontally. Increasing both size and sigma will increase the degree of blurring.
python
plt.figure(figsize=(8, 10.4))
for k, size in enumerate([3, 9, 27]):
for k2, sigma in enumerate([0, 10, 40]):
blur = cv2.GaussianBlur(im, (size, size), sigma)
ax = plt.subplot(3, 3, k2*3+k+1)
ax.imshow(cv2.cvtColor(blur, cv2.COLOR_BGR2RGB))
ax.set_xticks([])
ax.set_yticks([])
ax.set_title('blur size: %d\nsigma: %d' % (size, sigma))
plt.show()
opencv documentation https://docs.opencv.org/2.4/modules/core/doc/operations_on_arrays.html
You can make a mixed image like this. Also, you can enter a value larger than 1 in alpha and beta, but the value will be shaken off for pixels with a large value, so it will be mixed a little strangely like the image on the right end.
python
im2 = cv2.imread('../input/black_white.png')[:,:,::-1]
plt.imshow(cv2.cvtColor(im2, cv2.COLOR_BGR2RGB))
python
plt.figure(figsize=(15, 20))
for k, alpha in enumerate([0, 0.25, 0.5, 0.75, 1]):
for k2, gamma in enumerate([0, 0.5, 1, 2, 4]):
beta = 1 - alpha
im3 = cv2.addWeighted(im, alpha, im2, beta, gamma)
ax = plt.subplot(5, 5, 5*k2+k+1)
ax.imshow(cv2.cvtColor(im3, cv2.COLOR_BGR2RGB))
ax.set_title('alpha: %1.2f\nbeta: %1.2f\ngamma: %1.2f' % (alpha, beta, gamma))
ax.set_xticks([])
ax.set_yticks([])
plt.show()
You can emphasize the outline by drawing the blurred image from the original image.
python
blur = cv2.GaussianBlur(im, (9, 9), 27)
im3 = cv2.addWeighted(im, 1.5, blur, -0.5, 1)
plt.figure(figsize=(10, 5))
ax = plt.subplot(1, 3, 1)
ax.imshow(cv2.cvtColor(im, cv2.COLOR_BGR2RGB))
ax.set_title('base image')
ax.set_xticks([])
ax.set_yticks([])
ax = plt.subplot(1, 3, 2)
ax.imshow(cv2.cvtColor(blur, cv2.COLOR_BGR2RGB))
ax.set_title('gaussianBlur')
ax.set_xticks([])
ax.set_yticks([])
ax = plt.subplot(1, 3, 3)
ax.imshow(cv2.cvtColor(im3, cv2.COLOR_BGR2RGB))
ax.set_title('addWeighted')
ax.set_xticks([])
ax.set_yticks([])
plt.show()
Mixing the original image with alpha = 1.5 and the blurred image with beta = -0.5 will result in an image with enhanced contours.
Convolution filter function. It seems that various filtering can be implemented by changing the value of the array. The gaussianBlur () we were doing above can also be implemented with this function.
If you set kernel to [1], you can get the same image as the original image. Also, if you set some of the large array to 1 and all others to 0, you can translate as follows.
python
size = 21
kernel = np.zeros(size**2).reshape(size, size)
kernel[0, 0] = 1
kernel = kernel / np.sum(kernel)
print(kernel)
im4 = cv2.filter2D(im, -1, kernel)
# show picture
plt.figure(figsize=(7, 6))
ax = plt.subplot(1, 2, 1)
ax.imshow(cv2.cvtColor(im, cv2.COLOR_BGR2RGB))
ax.set_xticks([])
ax.set_yticks([])
ax.set_title('base image')
ax = plt.subplot(1, 2, 2)
ax.imshow(cv2.cvtColor(im4, cv2.COLOR_BGR2RGB))
ax.set_xticks([])
ax.set_yticks([])
ax.set_title('moved')
plt.show()
If there is not enough, the mirror image will be reversed.
If all kernels have the same value and a total of 1, it will be an average filter. Same as cv2.blur ().
python
def average_filter(size, im):
kernel = np.ones(size**2).reshape(size, size)
kernel = kernel / np.sum(kernel)
im4 = cv2.filter2D(im, -1, kernel)
return im4
plt.figure(figsize=(10, 5))
for k, size in enumerate([1, 21, 101]):
im4 = average_filter(size, im)
ax = plt.subplot(1, 3, k+1)
ax.imshow(cv2.cvtColor(im4, cv2.COLOR_BGR2RGB))
ax.set_title('size: %d' % size)
ax.set_xticks([])
ax.set_yticks([])
plt.show()
If you set the total to 1 and all but the center to -1 as shown below, the contour enhancement filter will be created.
\begin{pmatrix}
-1 & -1 & -1 & -1 & -1 & -1 & -1 \\
-1 & -1 & -1 & -1 & -1 & -1 & -1 \\
-1 & -1 & -1 & -1 & -1 & -1 & -1 \\
-1 & -1 & -1 & 49 & -1 & -1 & -1 \\
-1 & -1 & -1 & -1 & -1 & -1 & -1 \\
-1 & -1 & -1 & -1 & -1 & -1 & -1 \\
-1 & -1 & -1 & -1 & -1 & -1 & -1
\end{pmatrix}
python
def edge_filter(size, im):
kernel = np.full(size**2, -1).reshape(size, size)
pos = int((size-1)/2)
kernel[pos, pos] = size**2
print(kernel)
im4 = cv2.filter2D(im, -1, kernel)
return im4
im4 = edge_filter(7, im)
plt.figure(figsize=(6, 5))
ax = plt.subplot(1, 2, 1)
ax.imshow(cv2.cvtColor(im, cv2.COLOR_BGR2RGB))
ax.set_title('base image')
ax.set_xticks([])
ax.set_yticks([])
ax = plt.subplot(1, 2, 2)
ax.imshow(cv2.cvtColor(im4, cv2.COLOR_BGR2RGB))
ax.set_title('edge added')
ax.set_xticks([])
ax.set_yticks([])
plt.show()
It is similar to the above filter, but if you set the total to zero, it will be a filter that extracts only the outline.
python
def laplacian_filter(size, im):
kernel = np.ones(size**2).reshape(size, size)
pos = int((size-1)/2)
kernel[pos, pos] = -(size**2-1)
print(kernel)
im4 = cv2.filter2D(im, -1, kernel)
return im4
im4 = laplacian_filter(7, im)
plt.figure(figsize=(6, 5))
ax = plt.subplot(1, 2, 1)
ax.imshow(cv2.cvtColor(im, cv2.COLOR_BGR2RGB))
ax.set_title('base image')
ax.set_xticks([])
ax.set_yticks([])
ax = plt.subplot(1, 2, 2)
ax.imshow(cv2.cvtColor(im4, cv2.COLOR_BGR2RGB))
ax.set_title('laplacian filter')
ax.set_xticks([])
ax.set_yticks([])
plt.show()
Recommended Posts