J'écrirai que j'ai étudié la méthode de prétraitement des images pour l'apprentissage automatique. Le contenu est à moitié terminé, mais je pense que j'en ajouterai plus à l'avenir.
Windows10 python 3.6 opencv-python 4.1.2.30
documentation opencv http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html
Je vais créer une image de gradation appropriée et la binariser
# 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()
Binar utilisant la méthode d'Otsu
# 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()
Il est utilisé lorsqu'il y a une gradation de luminosité telle qu'une image photographique et que toute l'image ne peut pas être binarisée avec un seuil. 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()
Il existe différents types de seuils autres que la binarisation couramment utilisée.
# 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()
À partir de là, lisez un fichier image approprié et utilisez-le. Vous pouvez lire l'image comme numpy.array par cv2.imread (). J'utilise cv2.imshow () ou plt.imshow () pour afficher l'image, mais cv2.imshow () ne semble pas fonctionner avec le notebook jupyter, je vais donc l'afficher avec plt.imshow (). Cependant, alors que opencv lit traditionnellement la valeur dans BGR, plt.imshow () l'affiche comme RVB, donc après avoir échangé R et B avec cv2.cvtColor (src, cv2.COLOR_BGR2RGB) Je vais l'afficher.
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()
Cette fois je vais le faire avec cette image
documentation opencv http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_filtering/py_filtering.html
Un filtre qui brouille l'image. size est la taille verticale et horizontale, et sigma est l'écart type vertical et horizontal. Vous pouvez également spécifier sigma verticalement et horizontalement, mais s'il est omis, le même écart type sera utilisé à la fois verticalement et horizontalement. Augmenter à la fois la taille et le sigma augmentera le degré de flou.
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()
documentation opencv https://docs.opencv.org/2.4/modules/core/doc/operations_on_arrays.html
Vous pouvez créer une image mixte comme celle-ci. En outre, vous pouvez entrer une valeur supérieure à 1 en alpha et bêta, mais la valeur sera secouée pour les pixels avec une valeur élevée, elle sera donc mélangée un peu étrangement comme l'image à l'extrémité droite.
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()
Vous pouvez accentuer le contour en dessinant l'image floue à partir de l'image d'origine.
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()
Le mélange de l'image originale avec alpha = 1,5 et de l'image floue avec beta = -0,5 donnera une image avec des contours améliorés.
Fonction de filtre pliant. Il semble que divers filtrages peuvent être mis en œuvre en modifiant la valeur du tableau. Le gaussianBlur () que nous faisions ci-dessus peut également être implémenté avec cette fonction.
Si vous définissez le noyau sur [1], vous pouvez obtenir la même image que l'image d'origine. De plus, si une partie d'un tableau raisonnablement grand est définie sur 1 et toutes les autres sur 0, elle peut être déplacée en parallèle comme indiqué ci-dessous.
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()
L'image miroir sera inversée et apparaîtra s'il n'y en a pas assez.
Si tous les noyaux ont la même valeur et un total de 1, cela devient un filtre moyen. Identique à 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()
Comme indiqué ci-dessous, si vous définissez le total sur 1 et tout sauf le centre sur -1 pour créer un filtre d'amélioration des contours.
\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()
Il est similaire au filtre ci-dessus, mais si vous définissez le total sur zéro, ce sera un filtre qui extrait uniquement le contour.
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