18

I have drawn a contour around extreme points. Inside polygon figure I have others points. How to check if they are inside contour?

Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
POV
  • 11,293
  • 34
  • 107
  • 201

1 Answers1

36

You can use the cv2.pointPolygonTest() function available in OpenCV.

For example:

dist = cv2.pointPolygonTest(cnt,(50,50),True)

In this example we are checking whether the coordinate (50, 50) is present withing the contour cnt

  1. dist returns one of the following three:

    • Positive value if the point is inside the contour
    • Negative value if the point is outside the contour
    • Zero if the point is on the contour
  2. Within the function cv2.pointPolygonTest() the third parameter decides whether you want one of the following two :

    • If it is True, dist returns either the positive or negative distance of the point, if it is either inside or outside the contour respectively.
    • On the other hand, if it is set to False, it returns +1, -1 or 0 depending on the point lying inside, outside or on the contour respectively

See THE DOCS for more details

Illustration:

I added an example to show how it works. I considered the following image for which a contour was obtained:

enter image description here

I assumed the following points to be used as illustration:

(50, 70), (170, 152), (152, 48)

enter image description here

dist1 = cv2.pointPolygonTest(contours[0], (50, 70), True) #green 
dist2 = cv2.pointPolygonTest(contours[0], (170, 152), True) #blue
dist3 = cv2.pointPolygonTest(contours[0], (152, 48), True) #red

print('dist1 : ', dist1)
print('dist2 : ', dist2)
print('dist3 : ', dist3)

Output:

('dist1 : ', -45.17742799230607)
('dist2 : ', 49.9799959983992)
('dist3 : ', -0.0)
JoSSte
  • 2,953
  • 6
  • 34
  • 54
Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
  • Can I use this function to chek if point inside polygon? – POV Jun 03 '18 at 20:23
  • Yes. The polygon you are using must be passed as a contour – Jeru Luke Jun 03 '18 at 20:26
  • Okay I draw polygon as: `pts = np.array(b, np.int32) pts = pts.reshape((-1,1,2)) cv2.polylines(image,[pts],True,(0,255,0))` – POV Jun 03 '18 at 20:33
  • What I must to pass for `cv2.pointPolygonTest`? `pts`? – POV Jun 03 '18 at 20:34
  • 1
    Yes. Pass in one point at a time. If you have a bunch of points to test, pass them one after the other in a `list`. – Jeru Luke Jun 03 '18 at 20:35
  • 1
    Thx. I created a tetragon and have checked the position of the point inside them: L_DANGEROUS_ZONE = [ [57,356], [357,343], [828,847], [319,1069] ] ctr_dng = np.array(L_DANGEROUS_ZONE).reshape((-1,1,2)).astype(np.int32) dist = cv2.pointPolygonTest(ctr_dng,(center_x, center_y), True) if dist >= 0: k_dng += 1 – Orlov Const Sep 04 '20 at 09:56
  • Strangely, this function requires that the contour be of `np.dtype=int`. – GeneralCode Nov 06 '21 at 17:41