1

I trying to draw the contour in the ROI. But the vertices of the ROI appear on the left side of the image. I want to move the ROI to the place indicated in the photo, but I don't know how to do it. I'm new to OpenCV and Python, so any help is much appreciated. Here is my code.

enter image description here

# Object detected
            center_x = int(detection[0] * width)
            center_y = int(detection[1] * height)
            w = int(detection[2] * width)
            h = int(detection[3] * height)
            # Rectangle coordinates
            x = int(center_x - w / 2)
            y = int(center_y - h / 2)
            boxes.append([x, y, w, h])
            confidences.append(float(confidence))
            class_ids.append(class_id)

indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.4, 0.3)

for i in range(len(boxes)):
    if i in indexes:
        x, y, w, h = boxes[i]
        label = str(classes[class_ids[i]])
        confidence = confidences[i]
        color = colors[class_ids[i]]

        img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        ret, img_binary = cv2.threshold(img_gray, 15, 255, 0)
        roi = img_binary[y:y+h, x:x+w]
        contours, hierarchy = cv2.findContours(roi, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        cv2.drawContours(frame, contours, -1, (0,255,0), 3)
        print(roi.shape)
        print(x, y, w, h)
Stella
  • 23
  • 5
  • The coordinates of your `contours` are inside `box`. So simply shift them by `x` and `y`? Hard to tell without knowing what `boxes` is. – MSpiller Feb 17 '20 at 10:00
  • thank you for your comments. Boxes is a coordinate of the rectangle. I edit the code. please give me some comments. – Stella Feb 17 '20 at 10:03
  • Just shift by `x` and `y`. Give it a try. – MSpiller Feb 17 '20 at 10:09
  • Can I modify this code? "roi = img_binary[y:y+h, x:x+w]" – Stella Feb 17 '20 at 10:11
  • The ROI is correct. You have to shift the contours. Two ways to do so. 1. pass `x` and `y` as last argument (`offset`) to `findContours`. The returned `contours` will have coordinates relative to `img_binary`. Or 2. pass `x` and `y` as `offset` to `drawContours` – MSpiller Feb 17 '20 at 10:13
  • I'm terribly sorry, but I don't understand the meaning "offset". Can you explain in detail how to modify the code? Can i modify the code " cv2.drawContours(frame, contours, -1, (0,255,0), 3)"? – Stella Feb 17 '20 at 10:17

1 Answers1

3

The returned coordinates of the contours are relative to the ROI passed to findContours. I.e. the x coordinates of the contours are relative to the top-left corner of the ROI. Same for y.

As you want to display the contours inside of the original image and not inside of the ROI you have to shift them.

There are basically two options:

  1. pass x and y of your ROI to findContours like

    contours, hierarchy = cv2.findContours(roi, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE, offset=(x,y))
    

    The returned contours will then have coordinates relative to the original image.

  2. pass x and y to drawContours like

    cv2.drawContours(frame, contours, -1, (0,255,0), 3, offset=(x,y))
    

    This will leave the coordinates of your contours relative to the ROI and just display them inside of the original image.

What makes sense for you depends on your application.

The third option is to manually shift the contours by simply adding x to the first dimension and y to the second dimension. The output will be the same as 1.

MSpiller
  • 3,500
  • 2
  • 12
  • 24