如何在python opencv中完成/关闭轮廓?

Iro*_*Man 5 python opencv

我有一个Pi相机指向一张白色背景上的卡片.然而,局部阴影似乎阻止了我用于卡片检测的轮廓的关闭,这意味着整体检测失败.这是我的意思截图:

开放轮廓的屏幕截图

你可以看到它特别是在底角附近褴褛.这是我用来实现这个目的的代码:

gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
gray = cv2.blur(gray, (5,5))
gray = cv2.bilateralFilter(gray, 11, 17, 17) #blur. very CPU intensive.
cv2.imshow("Gray map", gray)

edges = cv2.Canny(gray, 30, 120)

cv2.imshow("Edge map", edges)

#find contours in the edged image, keep only the largest
# ones, and initialize our screen contour
# use RETR_EXTERNAL since we know the largest (external) contour will be the card edge.
_, cnts, _ = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:1]
screenCnt = None

# loop over our contours
for c in cnts:
    # approximate the contour
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.3 * peri, True)

    cv2.drawContours(image, [cnts[0]], -1, (0, 255, 0), 2)

    # if our approximated contour has four points, then
    # we can assume that we have found our card
    if len(approx) == 4:
        screenCnt = approx;
    break
Run Code Online (Sandbox Code Playgroud)

有没有办法迫使它关闭特定的轮廓?如果我模糊图像更多以平滑不起作用的阴影,因为它只是忽略那些没有边缘的角落.令人讨厌的是,距离关闭轮廓只有几个像素,但它永远不会......

编辑:我现在有一个更现实的设置,背景是米色,并有更多的阴影干扰.米色是必要的,因为有一些白色边框卡,所以白色不起作用.边缘检测主要在阴影所在的左侧失败.

在此输入图像描述

Eli*_*art 11

正如我在评论中提到的那样,在边界中"连接"线条的最简单方法之一是使用形态学运算符.在以下代码中,使用椭圆体形状扩大图像的边缘.这种技术允许我们合并靠近的线并填充一些空的空间.您可以在OpenCV文档中获得有关此主题的更多信息.

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(9,9))
dilated = cv2.dilate(image, kernel)
_, cnts, _ = cv2.findContours(dilated.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
Run Code Online (Sandbox Code Playgroud)

在这里,您可以看到原始边缘图像,扩张图像和使用扩张边缘获得的轮廓(使用原始屏幕截图的裁剪区域获得的图像):

但是,正如您可以看到并且也想象的那样,为更一般的情况解决这个问题更复杂,并且需要使用其他方法,并且可能比SO问题更广泛(或者至少以现在制定的方式).

通过查看更难的情况,我可以建议您使用其他图像表示来替换灰度输入图像(例如HSV色彩空间中的H通道),以减少或减弱阴影所产生的效果.您还可以探索问题中的一些约束:卡片总是以直线作为边框,并使用能够处理参数形式的方法,例如Hough Lines检测器.看看这个问题,它可能会给你一些关于如何改善结果的见解:如何使用javacv识别长度和宽度可变的方形或矩形?

备注:双边过滤的计算成本非常高,尤其是在使用RPi运行应用程序时.我建议投资其他一些替代方案,例如高斯滤波,以减少图片中的噪声量(假设您确实需要这样做).