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

后端 未结 3 723
梦如初夏
梦如初夏 2020-12-11 02:07

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

相关标签:
3条回答
  • 2020-12-11 02:23

    if you want to access all the points inside the convex hull, you can do masking

    I solve this by first painting my convex hull white colour with cv2.fillPoly() on a black frame

    1. First create black frame that follows your frame's shape
      black_frame = np.zeros_like(your_frame).astype(np.uint8)
    2. Paint the convex hull with white
      cv2.fillPoly(black_frame , [hull], (255, 255, 255))
    3. Create a mask by using numpy boolean indexing, it will produce a mask with True/False values inside, it will be True is the pixel value is white
      mask = black_frame == 255
    4. You can access your pixel values by getting the product between your frame and mask, if False, value will
      targetROI = your_frame * mask
    5. Access your pixels by using the mask.
    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
    
    0 讨论(0)
  • 2020-12-11 02:26

    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()
    
    0 讨论(0)
  • 2020-12-11 02:28

    Use pointPolygonTest function. Here's tutorial.

    0 讨论(0)
提交回复
热议问题