Apprentissage OpenCV + enregistrements de fonctions communes ④ : morphologie, correspondance de modèles et détection de mouvement

5. Transformation morphologique

Mettez d'abord le document officiel de transformation morphologique : [document du site officiel]

Les changements morphologiques sont des opérations simples basées sur la forme de l'image. L'objet de l'opération est généralement une image binaire, qui nécessite deux entrées, l'une est l'image d'entrée et l'autre est un élément structurel 3x3 (noyau), qui détermine la nature de l'opération de dilatation. Les opérations courantes sont la dilatation et l'érosion des images. Et leurs opérations avancées injectent Ouverture, Fermeture, Dégradé, etc.

La forme de l'élément structurel

MORPH_RECT Rectangle
MORPH_ELLIPSE Ellipse
MORPH_CROSS Croix

5.1 Extension

Très similaire à l'opération de convolution, il y a l'image A et les éléments structurels 3x3, et les éléments structurels glissent sur A. Calculer la valeur de pixel maximale couverte par l'élément structurel sur A pour remplacer l'élément central correspondant à l'élément structurel courant

Le rôle de l'extension :

  1. Augmenter les bords de l'objet d'un pixel
  2. lisser les bords de l'objet
  3. Distance objet à objet réduite
dst = cv.dilate(src, kernel)

5.2 Corrosion

Le processus de corrosion et de dilatation est similaire, la seule différence est que la valeur actuelle du pixel est remplacée par la valeur minimale couverte

Le rôle de l'érosion :

  1. Les bords de l'objet sont réduits d'un pixel
  2. Lissage des bords de l'objet
  3. Affaiblir la connexion entre les objets
dst = cv.erode(src, kernel)

5.3 Opération d'ouverture

L'érosion d'abord, puis l'expansion, principalement utilisée dans les images binaires ou les images en niveaux de gris

Érosion d'abord : laissez la plus petite valeur de couleur dans la fenêtre actuelle remplacer la valeur de couleur actuelle

Post-expansion : laissez la plus grande valeur de couleur dans la fenêtre actuelle remplacer la valeur de couleur actuelle

effet:

  1. Généralement utilisé pour éliminer les petits points d'interférence ou de bruit (lignes d'interférence des schémas de code de vérification)
  2. Cette opération peut être utilisée pour coopérer avec des éléments structurels pour extraire les lignes horizontales et verticales de l'image
dst_open = cv.morphologyEx(src, cv.MORPH_OPEN, kernel)

5.4 Opération de fermeture

L'expansion d'abord, l'érosion ensuite

Généralement utilisé pour combler les lacunes internes

dst_close = cv.morphologyEx(src2, cv.MORPH_CLOSE, kernel)

5.5 Exemples

import cv2 as cv

src = cv.imread("../img/morph-opening.jpg")
src2 = cv.imread("../img/morph-closing.jpg")

# 定义结构元素
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
print kernel

# 腐蚀操作
dst_erode = cv.erode(src, kernel)
# 膨胀操作
dst_dilate = cv.dilate(dst_erode, kernel)
# 开操作:先腐蚀再膨胀
dst_open = cv.morphologyEx(src, cv.MORPH_OPEN, kernel)
# 闭操作:先膨胀再腐蚀
dst_close = cv.morphologyEx(src2, cv.MORPH_CLOSE, kernel)

cv.imshow("j", src)
cv.imshow("dst_erode", dst_erode)
cv.imshow("dst_dilate", dst_dilate)
cv.imshow("dst_open", dst_open)
cv.imshow("j", src2)
cv.imshow("dst_close", dst_close)
cv.waitKey()

6. Correspondance des modèles

La correspondance de modèle consiste à trouver une petite zone correspondant à une sous-image donnée dans toute la zone de l'image.

Il existe 6 méthodes de mesure correspondantes fournies dans OpenCV.

  1. Méthode d'appariement par différence carrée CV_TM_SQDIFF
  2. Méthode d'appariement par différence quadratique normalisée CV_TM_SQDIFF_NORMED
  3. Méthode d'appariement de corrélation CV_TM_CCORR
  4. Méthode d'appariement de corrélation normalisée CV_TM_CCORR_NORMED
  5. Méthode d'appariement des coefficients CV_TM_CCOEFF
  6. Méthode d'appariement du coefficient de corrélation CV_TMCCOEFF_NORMED

En général, au fur et à mesure que l'on passe d'une mesure simple (la différence au carré) à une mesure plus complexe (la méthode des coefficients de corrélation), on peut obtenir des appariements de plus en plus précis. Cependant, cela se fera également au prix d'une quantité croissante de calculs. Quant à la méthode à choisir, analysez-la et comparez-la pour différentes situations d'appariement, et choisissez la meilleure solution qui convient le mieux à votre scénario d'application tout en tenant compte de la vitesse et de la précision. Remarque : Pour les méthodes SQDIFF et SQDIFF_NORMED, plus la valeur est petite, plus le résultat de correspondance est élevé, tandis que pour les autres méthodes, plus la valeur est grande, meilleur est l'effet de correspondance.

Exemple de code :

import cv2 as cv

# 加载原图
src = cv.imread("../img/zhaonimei.jpg")
cv.imshow("src", src)
# 加载模板
temp = cv.imread("../img/mei.jpg")
cv.imshow("template", temp)

# 输入参数:原图,模板,匹配度量方法
result = cv.matchTemplate(src, temp, cv.TM_SQDIFF)

# 将结果进行归一化处理
cv.normalize(result, result, 0, 1, cv.NORM_MINMAX)
print(result)

# 求最大值最小值
m_min, m_max, minLoc, maxLoc = cv.minMaxLoc(result)
print(minLoc, maxLoc, m_min, m_max)
cv.rectangle(src, (minLoc[0], minLoc[1]), (minLoc[0] + temp.shape[1], minLoc[1] + temp.shape[0]), (0, 0, 255), 2)

cv.imshow("dst", src)
cv.waitKey()

7. Détection de mouvement

Exemple de code :

import cv2 as cv

capture = cv.VideoCapture("../img/vtest.avi")
flag = capture.isOpened()
print(flag)

flag, frame = capture.read()

# 初始化BS模型
mog2 = cv.createBackgroundSubtractorMOG2(detectShadows=True)

# 形态学变换去掉噪声
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))

# frame = None
# Mask = None

while flag:
    flag, frame = capture.read()
    if not flag:
        break
    cv.imshow("frame", frame)
    Mask = mog2.apply(frame)

    #  thresh, mogMask = cv.threshold(Mask, 120, 255, cv.THRESH_BINARY)

    Mask = cv.morphologyEx(Mask, cv.MORPH_OPEN, kernel)

    _, contours, _ = cv.findContours(Mask, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)

    for i, contour in enumerate(contours):
        area = cv.contourArea(contour)
        if area > 500:
            cv.drawContours(frame, contours, i, (0, 0, 255), 2, cv.LINE_AA)
            rect = cv.boundingRect(contour)
            print(rect)
            cv.rectangle(frame, (rect[0], rect[1]), (rect[0] + rect[2], rect[1] + rect[3]), (255, 0, 0), 2)
    cv.imshow("frame", frame)
    cv.imshow("mog2", Mask)
    key = cv.waitKey(100)
    if key == 27:
        break

capture.release()
cv.destroyAllWindows()

Je suppose que tu aimes

Origine blog.csdn.net/Arcann/article/details/109450396
conseillé
Classement