3

I want to have a polygon region of interest and would like to perform an object detection algorithm within this area.

For example, the user gives some points and I want to create a polygon with them in my code (like the red region) and I want to perform my object detection code inside the red region.

The question is how can I search for object within this area and how should I implement the if conditions for defining IN and OUT areas?

Is there any efficient way to implement this in Python?

enter image description here

nathancy
  • 42,661
  • 14
  • 115
  • 137
Tindona
  • 430
  • 1
  • 16
  • To draw a polygon from a given set of points pass the points as an array to `cv2.polyline()` and get your polygon. You can mask the polygon region (ROI) over the original image using `cv2.bitwise_and()` – Jeru Luke Apr 28 '22 at 09:15
  • 1
    https://stackoverflow.com/questions/51121978/how-to-fill-a-polyline-in-opencv – Jeru Luke Apr 28 '22 at 09:35
  • @JeruLuke I don't want to draw it on my image, I want it to be a restriction for my "object recognition" algorithm. I don't know how to search for object within this area and how should I implement the if conditions for defining IN and OUT area – Tindona Apr 28 '22 at 09:54
  • 1
    I am suggesting you to mask the desired ROI on the image and then perform object detection – Jeru Luke Apr 28 '22 at 10:41
  • take the bounding box of the polygon, do your algorithm on that ROI, then discard what's in the bb but not in the polygon. opencv has a function for point-in-polygon test... or "draw" the polygon as a boolean mask and simply test the pixel's "color" (boolean value) – Christoph Rackwitz Apr 28 '22 at 12:18

1 Answers1

2

From what I understand, you're trying to differentiate between outer and inner contours. To determine what contours are IN and OUT, you can simply use contour hierarchy to differentiate between the two. Specifically, when using cv2.findContours you can use cv2.RETR_TREE to extract outer or inner contours. See understanding contour hierarchies: how to distinguish between contours for the full explanation. From the full topology map we are given, we can filter out the contours, the idea is that if a parent contour has inner contours, it means that it's an OUT contour and the child inside is the IN contour. Another case is if a contour has no inner child then we know it is an IN contour.

Here's an example to demonstrate:

Input image

enter image description here

Result

enter image description here

Code

import cv2

# Load image, grayscale, Otsu's threshold
image = cv2.imread('2.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

# Filter using contour hierarchy
cnts, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[-2:]
hierarchy = hierarchy[0]
for component in zip(cnts, hierarchy):
    currentContour = component[0]
    currentHierarchy = component[1]
    x,y,w,h = cv2.boundingRect(currentContour)
    # Has inner contours which means it is IN
    if currentHierarchy[2] < 0:
        cv2.putText(image, 'IN', (x,y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (36,255,12), 2)
    # No child which means it is OUT
    elif currentHierarchy[3] < 0:
        cv2.putText(image, 'OUT', (x,y-5), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (36,255,12), 2)

cv2.imshow('image', image)
cv2.waitKey()
Tindona
  • 430
  • 1
  • 16
nathancy
  • 42,661
  • 14
  • 115
  • 137