Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine if a point is inside or outside of a shape with opencv

Tags:

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?

like image 534
Soroosh Khoram Avatar asked Dec 09 '12 09:12

Soroosh Khoram


People also ask

Can OpenCV detect shapes?

OpenCV is an open source library used mainly for processing images and videos to identify shapes, objects, text etc.

What is XYWH in OpenCV?

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.

What is cv2 approxPolyDP?

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.


2 Answers

Use pointPolygonTest function. Here's tutorial.

like image 62
ArtemStorozhuk Avatar answered Sep 25 '22 02:09

ArtemStorozhuk


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() 
like image 33
nathancy Avatar answered Sep 24 '22 02:09

nathancy