Python OpenCV - 自定义掩码

时间:2018-05-18 08:22:31

标签: python opencv

我在这里有一个image。黄线内的区域是我感兴趣的区域,如此image所示,这也是我的目标之一。这是我的计划/步骤:

  1. 降噪,滤色,遮蔽和Canny边缘(DONE)
  2. 边缘坐标(DONE)
  3. example
  4. 选择某些顶点的坐标
  5. 使用这些顶点的坐标绘制多边形
  6. 以下是代码:

    import cv2
    import numpy as np
    from matplotlib import pyplot as plt
    
    frame = cv2.imread('realtest.jpg')
    
    denoisedFrame = cv2.fastNlMeansDenoisingColored(frame, None, 10, 10, 7, 21)
    
    HSVframe = cv2.cvtColor(denoisedFrame, cv2.COLOR_BGR2HSV) 
    
    lower_yellowColor = np.array([15,105,105]) 
    upper_yellowColor = np.array([25,255,255])
    
    whiteMask = cv2.inRange(HSVframe, lower_yellowColor, upper_yellowColor) 
    maskedFrame = cv2.bitwise_and(denoisedFrame, denoisedFrame, mask=whiteMask)
    
    grayFrame = cv2.cvtColor(maskedFrame, cv2.COLOR_BGR2GRAY)
    gaussBlurFrame = cv2.GaussianBlur(grayFrame, (5,5), 0)
    edgedFrame = cv2.Canny(grayFrame, 100, 200)
    
    #Coordinates of each white pixels that make up the edges
    ans = []
    
    for y in range(0, edgedFrame.shape[0]):
        for x in range(0, edgedFrame.shape[1]):
            if edgedFrame[y, x] != 0:
                ans = ans + [[x, y]]
    
    ans = np.array(ans)
    
    #print(ans.shape)
    #print(ans[0:100, :])
    
    
    cv2.imshow("edged", edgedFrame)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    如您所见,我已成功完成步骤编号(2)以获取构成边缘的每个白色像素的坐标。然而,对于下一步,步骤编号(3),我被卡住了。我尝试过编码here,但收到的错误是“ValueError:解压缩的值太多(预期2)”。

    请帮助教我找到合适的顶点,以构建尽可能接近黄线的多边形。

1 个答案:

答案 0 :(得分:0)

我已将答案分成两部分

第1部分 找到构建多边形的好顶点

包含边缘的图像周围所需的顶点可以使用OpenCV内置的cv2.findContours()函数完成。它返回带有轮廓,轮廓顶点和轮廓层次结构的图像。

可以通过两种方式找到轮廓的顶点:

  • cv2.CHAIN_APPROX_NONE绘制 ALL 每个轮廓上的坐标(边界点)

  • cv2.CHAIN_APPROX_SIMPLE绘制 ONLY 每个轮廓上最必要的坐标。它并不存储所有点。只存储最能代表轮廓的最需要的坐标。

在您的情况下,可以选择选项2。找到边缘后,您可以执行以下操作:

image, contours, hier = cv2.findContours(edgedFrame, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

contours包含图像edgedFrame

中每个轮廓的顶点

第2部分 构建多边形

Opencv还有一个内置函数cv2.convexHull()找到这些点后,您可以使用cv2.drawContours()绘制它们。

for cnt in contours:
    hull = cv2.convexHull(cnt)
    cv2.drawContours(frame, [hull], -1, (0, 255, 0), 2)

cv2.imshow("Polygon", frame)

enter image description here

通过在创建遮罩时进行更多预处理,可以获得所需边缘的更好近似值