numpy OpenCV pointPolygonTest()无法正常工作

92dk7w1h  于 2023-05-22  发布在  Go
关注(0)|答案(2)|浏览(119)

我想把一个图像分成6个相等的区域(如图所示),然后我想知道一个点属于哪个区域。我使用pointPolygonTest()来检查一个点是否在轮廓内,问题是它对某些区域有效,但对其他一些区域无效。
下面我展示了我的代码来实现这一点。我已经包括了一个测试,它的工作正确和其他地方,它不,因为它说的点不属于任何领域,而在图片中,它可以清楚地看到它。
输入:

img_path = "../tokyo.jpg"
im = cv2.imread(img_path)
im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)

xs = [0,im.shape[0]//2,im.shape[0]]
ys = [0,im.shape[1]//3,im.shape[1]//3*2,im.shape[1]]

contours = []

for i in range(len(xs)-1):
    for j in range(len(ys)-1):
        box = np.array([[xs[i],ys[j]],[xs[i],ys[j+1]],[xs[i+1],ys[j]],[xs[i+1],ys[j+1]]],dtype=np.int32)
        contours.append(box)

for c in contours:
    im = cv2.rectangle(im,(c[0]),(c[3]), (0, 255, 0), 10) # green
# im = cv2.circle(im, (400,400), radius=1, color=(255, 0, 0), thickness=10)
plt.imshow(im)
plt.show()

输出:

输入:

for i,c in enumerate(contours):
    distance = cv2.pointPolygonTest(c, (400,400), measureDist=False)
    if distance >= 0:
        print(f"Point is inside the contour {i+1}")
    else:
        print(f"Point is outside the contour {i+1}")

输出:
点在等高线1之外
点在等高线2之外
点在轮廓3之外
点在轮廓4之外
点在轮廓5之外
点在轮廓6之外
从图中可以清楚地看出,它应该说“点在轮廓5内”。下面你可以找到一个代码,它确实工作,只是通过改变距离几个像素,所以我不知道为什么会发生这种情况。也许我漏掉了什么任何帮助将不胜感激。
输入:将点从(400,400)更改为(300,400)

for i,c in enumerate(contours):
    distance = cv2.pointPolygonTest(c, (300,400), measureDist=False)
    ...

输出:
点在等高线1之外
点在轮廓2内
点在轮廓3之外
点在轮廓4之外
点在轮廓5之外
点在轮廓6之外
更新:我刚刚测试了几次,发现当点在图像的左半部分时,它确实有效,但当点在右侧时,它就无效了。不知道这背后的原因。

tyg4sfes

tyg4sfes1#

im.shape[0]-是图像的高度im.shape[1]-宽度

xs = [0,im.shape[1]//2,im.shape[1]]
ys = [0,im.shape[0]//3,im.shape[0]//3*2,im.shape[0]]
bbmckpt7

bbmckpt72#

密码:

box = np.array([
    [ xs[i],   ys[j]   ],
    [ xs[i],   ys[j+1] ],
    [ xs[i+1], ys[j]   ],
    [ xs[i+1], ys[j+1] ]
], dtype=np.int32)

这将按以下顺序定义点(假设您已经修复了宽度/高度混淆):

  • 左上角
  • 右上角
  • 左下角
  • 右下角

这不是等高线,这是一个自相交的沙漏。
这些点需要正确排序。把最后两个坐标重新排序。
注意:不,OpenCV轮廓没有什么特别的。它们只是一些 numpy 数组。它们的形状应该是(N, 1, 2),但(N, 2)可能也可以工作。

相关问题