24

背景が白でシンプルな形の画像があります(各画像には1つの形があります)。特定の点(x、y)が形状の内側にあるかどうかを確認したいと思います。opencvでそれを行うにはどうすればよいですか?

4

3 に答える 3

26

関数を使用pointPolygonTestします。これがチュートリアルです。

于 2012-12-09T09:17:28.613 に答える
16

ポイントがシェイプの内側、外側、またはエッジ上にあるかどうかを判断するには、を使用してポイントが輪郭内にあるかどうかを確認できますcv2.pointPolygonTest()。この関数は、、、またはを返し+1、ポイントが輪郭の内側、外側、または輪郭上にあるかどうかをそれぞれ示します。形状の輪郭がすでにあると仮定すると、輪郭と点を関数に渡すだけで済みます。-10(x,y)

result = cv2.pointPolygonTest(contour, (x,y), False) 

関数では、3番目の引数はmeasureDistです。の場合True、画像内の点と輪郭の間の最短距離を見つけます。の場合False、ポイントが輪郭の内側、外側、または輪郭上にあるかどうかを検出します。距離を見つけたくないので、measureDist引数をに設定しますFalse

正方形の輪郭を見つけて、ポイントが輪郭内にあるかどうかを確認する例を次に示します。


テスト画像

輪郭を見つけてポイントをチェックした後の画像

結果

ポイント1:-1.0

ポイント2:1.0

ポイント3:0.0

したがって、point1は外側、point2は内側、point3は輪郭上にあります。

import cv2

image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
canny = cv2.Canny(gray, 120, 255, 1)
cnts = cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

point1 = (25, 50)
point2 = (200, 250)
point3 = (200, 350)

# Perform check if point is inside contour/shape
for c in cnts:
    cv2.drawContours(image, [c], -1, (36, 255, 12), 2)
    result1 = cv2.pointPolygonTest(c, point1, False)
    result2 = cv2.pointPolygonTest(c, point2, False)
    result3 = cv2.pointPolygonTest(c, point3, False)

# Draw points
cv2.circle(image, point1, 8, (100, 100, 255), -1)
cv2.putText(image, 'point1', (point1[0] -10, point1[1] -20), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 0), lineType=cv2.LINE_AA)
cv2.circle(image, point2, 8, (200, 100, 55), -1)
cv2.putText(image, 'point2', (point2[0] -10, point2[1] -20), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 0), lineType=cv2.LINE_AA)
cv2.circle(image, point3, 8, (150, 50, 155), -1)
cv2.putText(image, 'point3', (point3[0] -10, point3[1] -20), cv2.FONT_HERSHEY_SIMPLEX, 1.0, (0, 0, 0), lineType=cv2.LINE_AA)

print('point1:', result1)
print('point2:', result2)
print('point3:', result3)
cv2.imshow('image', image)
cv2.waitKey()
于 2019-10-04T01:42:57.793 に答える
0

凸包内のすべてのポイントにアクセスしたい場合は、マスキングを行うことができます

これを解決するには、最初に凸包の白い色をcv2.fillPoly()で黒いフレームにペイントします。

  1. まず、フレームの形状に沿った黒いフレームを作成します
    black_frame = np.zeros_like(your_frame).astype(np.uint8)
  2. 凸包を白く塗る
    cv2.fillPoly(black_frame , [hull], (255, 255, 255))
  3. numpyブールインデックスを使用してマスクを作成します。True/False値が内部にあるマスクが生成されます。ピクセル値が白の場合はTrueになります。
    mask = black_frame == 255
  4. フレームとマスクの間に製品を取得することでピクセル値にアクセスできます。Falseの場合、値は
    targetROI = your_frame * mask
  5. マスクを使用してピクセルにアクセスします。
black_frame = np.zeros_like(your_frame).astype(np.uint8)
cv2.fillPoly(black_frame , [hull], (255, 255, 255))
mask = black_frame == 255
targetROI = your_frame * mask
于 2020-10-18T15:58:08.237 に答える