繁体   English   中英

如何在opencv / python中找到轮廓上的特定点

[英]How to find a specific point on a contour in opencv/python

我使用opencv来创建一些轮廓,我需要识别轮廓上的特定点,这通常是“V”形的最内点。 在附图中,我想要识别的点由绿色箭头显示。

例

左边是一个简单的案例,可以通过计算轮廓的凸包,然后找到离船体最远的点来进行识别(例如)。

然而,在附加图像的右侧是一个更加困难的情况,而不是1个轮廓,我得到几个,并且不存在漂亮的“V”形状,使得无法识别“V”的最内点。 如红色虚线所示,一种解决方案可能是推断较高的轮廓,直到它与较低的轮廓相交。 有谁知道我怎么会这样做? 或者有更好的解决方案?

为了记录,我尝试过:

  • 扩张/侵蚀(当多个轮廓靠近时工作,否则不行)

  • 霍夫变换p(往往错误定位目标点)

任何指针都将非常感激。

此解决方案适用于您提供的两个图像。 对于具有类似着色和“v”形(或至少部分“v”形)指向右侧的所有其他图像,这也应该是一个很好的解决方案。

我们先来看看更简单的图像。 我开始使用颜色空间分割图像。

# Convert frame to hsv color space
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# Define range of pink color in HSV
(b,r,g,b1,r1,g1) = 0,0,0,110,255,255
lower = np.array([b,r,g])
upper = np.array([b1,r1,g1])
# Threshold the HSV image to get only pink colors
mask = cv2.inRange(hsv, lower, upper)

色彩空间

接下来,我找到了mid_point ,在该行的上方和下方有相同数量的白色。

# Calculate the mid point
mid_point = 1
top, bottom = 0, 1
while top < bottom:
    top = sum(sum(mask[:mid_point, :]))
    bottom = sum(sum(mask[mid_point:, :]))
    mid_point += 1

然后,我从中点开始填充图像:bg = np.zeros((h + 2,w + 2),np.uint8)

kernel = np.ones((k_size, k_size),np.uint8)  
cv2.floodFill(mask, bg, (0, mid_point), 123)

floodfilled

现在我有了填充图像,我知道我要找的是距离图像右侧最近的灰色像素。

# Find the gray pixel that is furthest to the right
idx = 0
while True:
    column = mask_temp[:,idx:idx+1]
    element_id, gray_px, found = 0, [], False
    for element in column:
        if element == 123:
            v_point = idx, element_id
            found = True
        element_id += 1
    # If no gray pixel is found, break out of the loop
    if not found: break
    idx += 1

结果:

RESULT1

现在为更难的形象。 在右侧的图像中,'v'未完全连接:

不连接

为了关闭'v',我迭代地扩大了检查它是否连接的掩码:

# Flood fill and dilate loop
k_size, iters = 1, 1
while True:
    bg = np.zeros((h+2, w+2), np.uint8)
    mask_temp = mask.copy()    
    kernel = np.ones((k_size, k_size),np.uint8)    
    mask_temp = cv2.dilate(mask_temp,kernel,iterations = iters)
    cv2.floodFill(mask_temp, bg, (0, mid_point), 123)
    cv2.imshow('mask', mask_temp)
    cv2.waitKey()
    k_size += 1
    iters += 1
    # Break out of the loop of the right side of the image is black
    if mask_temp[h-1,w-1]==0 and mask_temp[1, w-1]==0: break

扩张

这是结果输出:

OUTPUT2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM