如何在opencv python中对附近的轮廓进行分组?

问题描述 投票:2回答:1

我想检测斑马线。我试图使用contour找出图像中斑马线的坐标,但是它给出了不同白框的输出(仅斑马线中的白线)。但是我需要整个斑马线的坐标。

[请让我知道对轮廓进行分组的方法,或建议我另外一种检测斑马线的方法。

Input image

Output image obtained

Expected output

import cv2
import numpy as np
image = cv2.imread('d.jpg',-1)
paper = cv2.resize(image,(500,500))
ret, thresh_gray = cv2.threshold(cv2.cvtColor(paper, cv2.COLOR_BGR2GRAY),
                        200, 255, cv2.THRESH_BINARY)
image, contours, hier = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for c in contours:
    rect = cv2.minAreaRect(c)
    box = cv2.boxPoints(rect)
    # convert all coordinates floating point values to int
    box = np.int0(box)
    cv2.drawContours(paper, [box], 0, (0, 255, 0),1)
cv2.imshow('paper', paper)
cv2.imwrite('paper.jpg',paper)
cv2.waitKey(0)
image opencv image-processing video-processing opencv-contour
1个回答
0
投票

您可以closing形态学上的操作来缩小缺口。

我建议以下阶段:

  • thresh_gray中查找轮廓。
  • 以很小的面积(噪声)擦除轮廓。
  • 以低长宽比擦除轮廓(假设斑马线必须长而窄。
  • 使用morphologyEx执行关闭形态操作-关闭合并关闭组件。
  • 删除并关闭后,再次在图像中找到轮廓。在最后阶段,忽略小的轮廓。

这里是工作代码示例:

import cv2
import numpy as np

image = cv2.imread('d.jpg', -1)
paper = cv2.resize(image, (500,500))
ret, thresh_gray = cv2.threshold(cv2.cvtColor(paper, cv2.COLOR_BGR2GRAY), 200, 255, cv2.THRESH_BINARY)
image, contours, hier = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

# Erase small contours, and contours which small aspect ratio (close to a square)
for c in contours:
    area = cv2.contourArea(c)

    # Fill very small contours with zero (erase small contours).
    if area < 10:
        cv2.fillPoly(thresh_gray, pts=[c], color=0)
        continue

    # https://stackoverflow.com/questions/52247821/find-width-and-height-of-rotatedrect
    rect = cv2.minAreaRect(c)
    (x, y), (w, h), angle = rect
    aspect_ratio = max(w, h) / min(w, h)

    # Assume zebra line must be long and narrow (long part must be at lease 1.5 times the narrow part).
    if (aspect_ratio < 1.5):
        cv2.fillPoly(thresh_gray, pts=[c], color=0)
        continue


# Use "close" morphological operation to close the gaps between contours
# https://stackoverflow.com/questions/18339988/implementing-imcloseim-se-in-opencv
thresh_gray = cv2.morphologyEx(thresh_gray, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (51,51)));

# Find contours in thresh_gray after closing the gaps
image, contours, hier = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

for c in contours:
    area = cv2.contourArea(c)

    # Small contours are ignored.
    if area < 500:
        cv2.fillPoly(thresh_gray, pts=[c], color=0)
        continue

    rect = cv2.minAreaRect(c)
    box = cv2.boxPoints(rect)
    # convert all coordinates floating point values to int
    box = np.int0(box)
    cv2.drawContours(paper, [box], 0, (0, 255, 0),1)

cv2.imshow('paper', paper)
cv2.imwrite('paper.jpg', paper)
cv2.waitKey(0)
cv2.destroyAllWindows()

thresh_gray删除小而方形的轮廓之前:enter image description here

thresh_gray在删除小而方形的轮廓后:enter image description here

thresh_gray关闭操作后:enter image description here

最终结果:enter image description here


备注:我对使用形态学运算来缩小差距的好处感到怀疑。相反,最好使用基于几何的智能逻辑。

© www.soinside.com 2019 - 2024. All rights reserved.