Determine if a point is inside or outside of a shape with opencv
Solution 1
Use pointPolygonTest
function. Here's tutorial.
Solution 2
To determine if a point is inside, outside, or on the edge of a shape you can check if the point is within a contour using cv2.pointPolygonTest()
. The function returns +1
, -1
, or 0
to indicate if a point is inside, outside, or on the contour, respectively. Assuming we already have the contour of the shape, we can simply pass the contour and the (x,y)
point to the function.
result = cv2.pointPolygonTest(contour, (x,y), False)
In the function, the third argument is measureDist
. If it is True
, it finds the shortest distance between a point in the image and a contour. If False
, it finds whether the point is inside, outside, or on the contour. Since we don't want to find the distance, we set the measureDist
argument to False
Here's an example that finds the square contour then checks if the points are within the contour
Test image
Image after finding contour and checking points
Results
point1: -1.0
point2: 1.0
point3: 0.0
Therefore point1 is outside, point2 is inside, and point3 is on the contour
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()
Soroosh Khoram
Updated on July 10, 2022Comments
-
Soroosh Khoram almost 2 years
I have images with white background and simple shapes in them (each image has one shape). I want to determine if a certain point (x,y) is inside the shape or not. How can I do that with opencv?