【问题标题】:How to detect edge if edges of an object has same colour as background如果对象的边缘与背景颜色相同,如何检测边缘
【发布时间】:2018-11-09 01:59:36
【问题描述】:

我的任务是构建一个车牌检测系统,如果车牌与汽车的油漆颜色(背景)相同,我的代码将无法工作。

看看下面这张图。

我尝试了各种边缘检测技术,但我的发现它们几乎不起作用。

这是我的图像处理管道:

  • 从图像中提取灰色通道。
  • 通过迭代双边滤波降低噪声
  • 使用自适应阈值检测边缘
  • 稍微扩大边缘
  • 根据一些启发式方法定位轮廓。

边缘检测部分在车牌区域周围表现不佳。

管道运行良好,如果汽车的油漆颜色与车牌不同,我能够检测到车牌。

代码

def rectangleness(hull):
    rect = cv2.boundingRect(hull)
    rectPoints = np.array([[rect[0], rect[1]], 
                           [rect[0] + rect[2], rect[1]],
                           [rect[0] + rect[2], rect[1] + rect[3]],
                           [rect[0], rect[1] + rect[3]]])
    intersection_area = cv2.intersectConvexConvex(np.array(rectPoints), hull)[0] 
    rect_area = cv2.contourArea(rectPoints)
    rectangleness = intersection_area/rect_area
    return rectangleness


def preprocess(image):
    image = imutils.resize(image, 1000)

    # Attenuate shadows by using H channel instead of converting to gray directly
    imgHSV = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    _, _, gray = cv2.split(imgHSV)

    # Reduce noise while preserve edge with Iterative Bilaterial Filtering
    blur = cv2.bilateralFilter(gray, 11, 6, 6)

    # Detect edges by thresholding
    edge = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 5)

    # Dilate edges, kernel size cannot be too big as some fonts are very closed to the edge of the plates
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2, 2))
    dilated = cv2.dilate(edge, kernel)

    # Detect contours
    edge, contours, _ = cv2.findContours(dilated, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

    # Loop through contours and select the most probable ones
    contours = sorted(contours, key = cv2.contourArea, reverse=True)[:10]

    for contour in contours:
        perimeter = cv2.arcLength(contour, closed=True)
        approximate = cv2.approxPolyDP(contour, 0.02*perimeter, closed=True)

        if len(approximate) == 4:
            (x, y, w, h) = cv2.boundingRect(approximate)
            whRatio = w / h

            # Heuristics:
            # 1. Width of plate should at least be 2x greater than height
            # 2. Width of contour should be more than 5 (eliminate false positive)
            # 3. Height must not be too small
            # 4. Polygon must resemble a rectangle
            if (2.0 < whRatio < 6.0) and (w > 5.0) and (h > 20):
                hull = cv2.convexHull(approximate, returnPoints=True)
                if rectangleness(hull) > 0.75:
                    print("X Y {} {}".format(x, y))
                    print("Height: {}".format(h))
                    print("Width : {}".format(w))
                    print("Ratio : {}\n".format(w/h))
                    cv2.drawContours(image, [approximate], -1, (0, 255, 0), 2)

    cv2.imshow("Edge", edge)
    cv2.imshow("Frame", image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

【问题讨论】:

  • 您需要检测车牌上的文字,而不是车牌本身。
  • 您必须接受在某些情况下无法检测到印版并单独处理字符。

标签: python opencv image-processing edge-detection


【解决方案1】:

您可以使用cv2.morphologyEx 使板块区域变得更加明显。下一步是寻找轮廓并设置合理的条件来提取包含车牌的轮廓。如果你愿意,你可以看看这个github repository,我和我的朋友在这里展示了关于车牌检测和识别的详细步骤。

import cv2
import numpy as np

img = cv2.imread("a.png")

imgBlurred = cv2.GaussianBlur(img, (7, 7), 0)
gray = cv2.cvtColor(imgBlurred, cv2.COLOR_BGR2GRAY) # convert to gray
sobelx = cv2.Sobel(gray, cv2.CV_8U, 1, 0, ksize=3) # sobelX to get the vertical edges

ret,threshold_img = cv2.threshold(sobelx, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

morph_img_threshold = threshold_img.copy()
element = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=(22, 3))
cv2.morphologyEx(src=threshold_img, op=cv2.MORPH_CLOSE, kernel=element, 
dst=morph_img_threshold)

cv2.imshow("img", img)
cv2.imshow("sobelx", sobelx)
cv2.imshow("morph_img_threshold", morph_img_threshold)

cv2.waitKey()
cv2.destroyAllWindows()

【讨论】:

  • 您好,感谢您的输入!在这个问题发布后不久,我实际上已经在我的代码中集成了类似的形态逻辑,并尝试了几种内核组合。然而,在几个约束方面,结果仍然相当不一致和不准确。稍后会看看你的回购!谢谢!
  • 不客气。我会考虑你的情况,我们稍后再讨论。
猜你喜欢
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 2020-06-15
  • 1970-01-01
  • 2014-12-22
  • 2018-11-14
  • 2019-07-30
  • 1970-01-01
相关资源
最近更新 更多