2

I have written a Python script that basically parses a video frame by frame and uses feature matching + Homography to detect similarities to a given image and draws a bounding box around the area where the image appears in the video. I'm very new to OpenCV, hence I cannot really understand which function to use to draw a filled rectangle instead of a bounding box (I'm using polylines).

I'm guessing I have to use 'fillpoly' or 'fillConvexPoly' but I'm confused as to which parameters to use and how to implement it. Here's my code so far.

    import cv2
    import numpy as np
    img = cv2.imread("template.png", cv2.IMREAD_GRAYSCALE) 
    cap = cv2.VideoCapture("video.mp4")

    fourcc = cv2.VideoWriter_fourcc(*'xvid')
    out = cv2.VideoWriter('output.avi',fourcc, 25.0, (1280,718))

    # Features
    sift = cv2.xfeatures2d.SIFT_create()
    kp_image, desc_image = sift.detectAndCompute(img, None)

    # Feature matching
    index_params = dict(algorithm=0, trees=5)
    search_params = dict()
    flann = cv2.FlannBasedMatcher(index_params, search_params)

    while True :
        _, frame = cap.read()
        grayframe = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        kp_grayframe, desc_grayframe = sift.detectAndCompute(grayframe, None)
        matches = flann.knnMatch(desc_image, desc_grayframe, k=2)

        good_points = []
        for m, n in matches:
            if m.distance < 0.6 * n.distance:
                good_points.append(m)

        if (len(good_points)>10):
            query_pts = np.float32([kp_image[m.queryIdx].pt for m in good_points]).reshape(-1, 1, 2)
            train_pts = np.float32([kp_grayframe[m.trainIdx].pt for m in good_points]).reshape(-1, 1, 2)
            matrix, mask = cv2.findHomography(query_pts, train_pts, cv2.RANSAC, 5.0)
            matches_mask = mask.ravel().tolist()

            # Perspective transform
            h, w = img.shape
            pts = np.float32([[0, 0], [0, h], [w, h], [w, 0]]).reshape(-1, 1, 2)
            dst = cv2.perspectiveTransform(pts, matrix)

            homography = cv2.polylines(frame, [np.int32(dst)], True, (0,255, 0), 3) #this is the line i want to change
            out.write(homography)
            cv2.imshow("Homography", homography)

        else:
            cv2.imshow("Homography", grayframe)


        cv2.imshow("grayFrame", grayframe)

        key = cv2.waitKey(1)
        if key & 0xFF == ord('q'):
            break

    cap.release()
    out.release()
    cv2.destroyAllWindows()
Anirban Nath
  • 41
  • 1
  • 4
  • Hi, Anriban Nath! If you edit your question adding **Python** and **OpenCV** versions you're using it would let people help you easly. – gsscoder Dec 14 '19 at 05:49

1 Answers1

4

As you mention yourself, you can use cv2.fillPoly().

You may want to take a look to the cv2.fillPoly() documentation here.

or to these related SO questions:

import cv2
import numpy as np

image = np.zeros(shape=(512, 512, 3), dtype=np.uint8)
points = np.array([[225, 150], [103, 320], [350, 250], [222, 245]],
                  dtype=np.int32)

cv2.fillPoly(image, [points], (0, 255, 0))
cv2.imshow('polygon', image)
cv2.waitKey(0)

enter image description here

ndrplz
  • 1,584
  • 12
  • 16