0

I have to extract this: object

from the given image:

image I tried contour detection but that gives all the contours. But I specifically need that object in that image.

My idea is to:

  1. Find the objects in the image
  2. Draw bounding box around them
  3. Crop them and save them individually.

I am working with opencv and using python3, which I am fairly new to.

As seen there are three objects similar to given template but of different sizes. Also there are other boxes which are not the area of interest. After cropping I want to save them as three separate images. Is there a solution to this situation ?

I tried multi-scale template matching with the cropped template.

Here is an attempt:

# import the necessary packages
import numpy as np
import argparse
import imutils
import glob
import cv2

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-t", "--template", required=True, help="Path to template image")

args = vars(ap.parse_args())

# load the image image, convert it to grayscale, and detect edges
template = cv2.imread(args["template"])
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
template = cv2.Canny(template, 50, 200)
(tH, tW) = template.shape[:2]
image = cv2.imread('input.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# loop over the scales of the image
for scale in np.linspace(0.2, 1.0, 20)[::-1]:
# resize the image according to the scale, and keep track
# of the ratio of the resizing
    resized = imutils.resize(gray, width = int(gray.shape[1] * scale))
    r = gray.shape[1] / float(resized.shape[1])
    # if the resized image is smaller than the template, then break
    # from the loop
    if resized.shape[0] < tH or resized.shape[1] < tW:
        break
    # detect edges in the resized, grayscale image and apply template
    # matching to find the template in the image
    edged = cv2.Canny(resized, 50, 200)
    res = cv2.matchTemplate(edged, template, cv2.TM_CCOEFF)
loc = np.where( res >= 0.95)
for pt in zip(*loc[::-1]):
        cv2.rectangle(image, int(pt*r), (int((pt[0] + tW)*r), int((pt[1] + tH)*r)), (0,255,0), 2)

cv2.imwrite('re.png',image)

Result that I am getting: resultExpected result is bounding boxes around all the post-it boxes

1 Answers1

0

I'm currently on mobile so I can't really write code, but this link does exactly what you're looking for!

If anything isn't clear I can adapt the code to your example later this evening, when I have acces to a laptop.

In your case I would crop out the content of the shape (the post-it) and template match just on the edges. That'll make sure it's not thrown off by the text inside.

Good luck!

Victor Sonck
  • 396
  • 3
  • 5
  • I was trying the same thing. But it doesn't work for the same reason you mentioned(the inside text). How should I just match the edges then? I will try cropping the inside of the template and get back. – Divyasha Agrawal Feb 08 '19 at 11:11
  • The only thing that is similar between the template and what you're searching are the edges and the funny corner in the top right. So ideally you would crop the template so that only the edges are left. That way it can match any post-it regardless of what is inside – Victor Sonck Feb 08 '19 at 11:21
  • I tried cropping the template, but it doesn't seem to work. I have updated the question above according your suggestion. Can you kindly check once? Thank you so much for your time. – Divyasha Agrawal Feb 11 '19 at 08:34