opencv-python Introduction au traitement d'image

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.

Environnement d'essai

Windows10 python 3.6 opencv-python 4.1.2.30

Traitement des seuils: cv.Threshold (src, threshold, maxValue, thresholdType)

documentation opencv http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html

Binariser en spécifiant un seuil

Je vais créer une image de gradation appropriée et la binariser image.png

# 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()

Le seuil est automatiquement défini et binarisé

Binar utilisant la méthode d'Otsu image.png

# 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()

Binarisation avec seuil dynamique: adaptiveThreshold (src, maxValue, adaptiveMethod, thresholdType, blockSize, C [, dst])

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. image.png 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()

Autre traitement de seuil

Il existe différents types de seuils autres que la binarisation couramment utilisée. image.png

# 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()

Charger l'image: cv2.imread ()

À 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

Image floue: cv2.GaussianBlur (src, (taille, taille), sigma)

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()

Synthèse alpha: addWeighted (src1, alpha, src2, beta, gamma)

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()

Amélioration des contours avec flou et composition alpha

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.

Filtrage: cv2.filter2D (src, noyau)

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.

Mouvement parallèle

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()

image.png L'image miroir sera inversée et apparaîtra s'il n'y en a pas assez.

Filtre moyen

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()

image.png

Filtre d'amélioration des contours

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}

image.png

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()

Filtre d'extraction de contour

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. image.png

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()

(Prévu pour être ajouté)

Recommended Posts

opencv-python Introduction au traitement d'image
[Introduction à TensorBoard: image] TensorFlow Visualisez le traitement d'image pour approfondir la compréhension
Introduction à l'analyse d'image opencv python
[Traitement d'image] Postérisation
Introduction à Scrapy (1)
Introduction à Scrapy (3)
Premiers pas avec Supervisor
Introduction à Tkinter 1: Introduction
traitement d'image python
Introduction au remplissage d'image Python Remplissage d'image à l'aide d'ImageDataGenerator
Introduction à PyQt
Introduction à Scrapy (2)
[Linux] Introduction à Linux
Introduction à Scrapy (4)
Introduction à discord.py (2)
Traitement d'image 100 coups ①
[Introduction à TensorBoard] Visualisez le traitement TensorFlow pour approfondir la compréhension
Comment utiliser la bibliothèque de traitement d'image basée sur PyTorch "Kornia"
Introduction à Lightning Pytorch
Premier traitement d'image Python
Premiers pas avec le Web Scraping
Introduction aux baies non paramétriques
Introduction à EV3 / MicroPython
Lire le traitement d'image numérique
Introduction au langage Python
Introduction à la reconnaissance d'image TensorFlow
Introduction à OpenCV (python) - (2)
Introduction à PyQt4 Partie 1
Traitement d'image avec Python
Introduction à l'injection de dépendances
Introduction à Private Chainer
Introduction à l'apprentissage automatique
Traitement d'image avec PIL
[Introduction à Python] Comment utiliser l'instruction while (traitement répétitif)
100 coups sur le traitement d'image !! (021-030) Je veux faire une pause ...
[Chapitre 5] Introduction à Python avec 100 coups de traitement du langage
Introduction au traitement parallèle distribué Python par Ray
[Chapitre 6] Introduction à scicit-learn avec 100 coups de traitement du langage
[Chapitre 3] Introduction à Python avec 100 coups de traitement du langage
[Chapitre 2] Introduction à Python avec 100 coups de traitement du langage
[Chapitre 4] Introduction à Python avec 100 coups de traitement du langage
AOJ Introduction à la programmation Sujet 1, Sujet 2, Sujet 3, Sujet 4
Introduction au module de papier électronique
Traitement d'image avec Python (partie 2)
Introduction à l'algorithme de recherche de dictionnaire
Introduction à la méthode Monte Carlo
OpenCV-Détecte les différences d'image similaires en Python
Traitement d'image avec PIL (Pillow)
Introduction à Python Django (2) Win
Introduction à l'écriture de Cython [Notes]
Introduction à Private TensorFlow
Une introduction à l'apprentissage automatique
[Introduction à cx_Oracle] Présentation de cx_Oracle
Une super introduction à Linux
AOJ Introduction à la programmation Sujet n ° 7, Sujet n ° 8