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?
OpenCV is an open source library used mainly for processing images and videos to identify shapes, objects, text etc.
The convention is as follows, it is x,y,w,h as you said, x,y are the coordinates for the top left corner of the box, and w,h are just the width and height, that's it, and similarily the origin of the image is from the top left, not bottom left, as specified by your drawing.
The process of approximating the shape of a contour of a given polygon to the shape of the original polygon to the specified precision is called approximation of a shape of the contour. We make use of a function in OpenCV called approxPolyDP() function to perform an approximation of a shape of a contour.
Use pointPolygonTest
function. Here's tutorial.
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With