答案 0 :(得分:3)
首先,我想指出的是,该答案是用Python编写的,旨在为如何解决此类问题提供一个思路。
第二,定义轮廓的最高点和最左边是一个问题,因为轮廓的形状变化很大。这意味着左右的最极端值并不总是与最高值互补。以下面的图片为例:
右上方的红点是向北的最高点,但不是最右边的(这是所有4个点中最左的点),而底下的红点是最右边的点,但不是最高的点(实际上是是最低的北方!)。介于两者之间并且可以满足上述条件。
话虽如此,我已经用Python为您的图片中描述的最相似的解决方案制作了一个脚本,以显示我将如何尝试解决该问题。可能不是您想要的,可能会有更好的解决方案,但这可能会给您一个想法或弄清您的实际需求。
我自由下载了示例图片并对其进行了一些编辑,因此我可以举一个例子。这是我的“原语”:
我已经提取了图像的轮廓并选择了最大的轮廓-返回点数组。然后,我在X坐标(最右边的点)和最低Y坐标(最北点)中提取了最高值。因为轮廓没有直线,所以我为最重要的点的最大变化点设定了一个阈值(在您的情况下,数字可能会不同-我的情况是+-3)。然后,我将一个阈值中所有最正确的点添加到一个列表中,并将所有最北点附加到另一个列表中。然后从最左端的列表中选择X坐标最低的点,在另一个列表中的最右点选择Y坐标最低的点。
这是结果:
希望它会有所帮助。干杯!
Python示例:
import cv2
import numpy as np
img = cv2.imread('uplupr.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, threshold = cv2.threshold(gray,170,255,cv2.THRESH_BINARY)
im, contours, hierarchy = cv2.findContours(threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
mask = np.zeros(img.shape, dtype="uint8")
cnt = max(contours, key=cv2.contourArea)
cv2.drawContours(mask, [cnt], -1, (255,255,255), 1)
top_right_append = 0
top_up_append = 1000
point_up = []
point_right = []
for i in cnt:
top_up = int(i[:,1])
top_right = int(i[:, 0])
if top_right > top_right_append:
top_right_append = int(top_right)
if top_up < top_up_append:
top_up_append = int(top_up)
for i in cnt:
if int(i[:,1]) < top_up_append+3:
up = (int(i[:,0]), int(i[:,1]))
point_up.append(up)
for i in cnt:
if int(i[:,0]) > top_right_append-3:
right = (int(i[:,0]), int(i[:,1]))
point_right.append(right)
point_up.sort(key=lambda tup: tup[0])
point_right.sort(key=lambda tup: tup[1])
cv2.circle(mask,(point_up[0]), 4, (0,0,255), -1)
cv2.circle(mask,(point_right[0]), 4, (0,0,255), -1)
cv2.imshow('image', mask)