Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw bounding box on best matches?

How can I draw a bounding box on best matches in BF MATCHER using Python?

like image 519
Ali110 Avatar asked Jul 31 '18 05:07

Ali110


People also ask

What is used to draw the bounding boxes?

An annotator will draw bounding boxes around other vehicles and label them. This helps train an algorithm of computer vision models to understand what vehicles look like. Annotating objects such as vehicles, traffic signals, and pedestrians makes it possible for autonomous vehicles to maneuver busy streets safely.

How do you draw a bounding box around contours?

The basic idea is to find the Xmin, Xmax, Ymin, Ymax of each identified coordinates of the contour and then create a rectangle using it. Lets understand this with an example: Import the necessary libraries, read the input file, convert it to grayscale and plot it.

What is bounding box format?

A bounding box (usually shortened to bbox) is an area defined by two longitudes and two latitudes, where: Latitude is a decimal number between -90.0 and 90.0. Longitude is a decimal number between -180.0 and 180.0.


1 Answers

Here is a summary of the approach it should be a proper solution:

  1. Detect keypoints and descriptors on the query image (img1)
  2. Detect keypoints and descriptors on the target image (img2)
  3. Find the matches or correspondences between the two sets of descriptors
  4. Use the best 10 matches to form a transformation matrix
  5. Transform the rectangle around img1 based on the transformation matrix
  6. Add offset to put the bounding box at the correct position
  7. Display the result image (as below).

BF Matching Result Image (Preview)

Here is the code:

import numpy as np
import cv2
from matplotlib import pyplot as plt

img1 = cv2.imread('box.png', 0)          # query Image
img2 = cv2.imread('box_in_scene.png',0)  # target Image

# Initiate SIFT detector
orb = cv2.ORB_create()

# find the keypoints and descriptors with ORB
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)

# create BFMatcher object
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)

# Match descriptors.
matches = bf.match(des1,des2)

# Sort them in the order of their distance.
matches = sorted(matches, key = lambda x:x.distance)

good_matches = matches[:10]

src_pts = np.float32([ kp1[m.queryIdx].pt for m in good_matches     ]).reshape(-1,1,2)
dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good_matches ]).reshape(-1,1,2)
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0)
matchesMask = mask.ravel().tolist()
h,w = img1.shape[:2]
pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)

dst = cv2.perspectiveTransform(pts,M)
dst += (w, 0)  # adding offset

draw_params = dict(matchColor = (0,255,0), # draw matches in green color
               singlePointColor = None,
               matchesMask = matchesMask, # draw only inliers
               flags = 2)

img3 = cv2.drawMatches(img1,kp1,img2,kp2,good_matches, None,**draw_params)

# Draw bounding box in Red
img3 = cv2.polylines(img3, [np.int32(dst)], True, (0,0,255),3, cv2.LINE_AA)

cv2.imshow("result", img3)
cv2.waitKey()
# or another option for display output
#plt.imshow(img3, 'result'), plt.show()
like image 181
Howard GENG Avatar answered Sep 18 '22 11:09

Howard GENG