0

I have an image of pots of the same size, the user must crop an area (let's say he crops the first pot (top left corner)) of ​​the image and depending on the pattern designed or cropped by the user, I must automatically perform other cropping and save their coordinates. Is there another technique to do this without template matching or do you think I can improve my code to do it with template matching only?

So far I have tried with template matching and saved the coordinates of each corresponding matched, but as you can see in the attached image, the result is not quite satisfying because I don't match all the pots and for some area I draw several rectangles for just one pot (the more I lower the threshold). Any help is higly appreciated.

enter image description here

Here is my code

# import necessary dependies
import cv2
import numpy as np

# Read the source image
img_rgb = cv2.imread('image.jpg')

# Convert the source image to gray
img_gray = cv2.cvtColor(img_rgb, cv.COLOR_BGR2GRAY)

# Read the pattern image designed by the user
template = cv2.imread('mattern.png',0)

# Get the shape of the pattern image
w, h = template.shape[::-1]

# Apply cv2 template matching functon
res = cv2.matchTemplate(img_gray,template,cv.TM_CCOEFF_NORMED)

# List of coordinates of the matched templates
list_coordinates = []
labeled_coordinates = []

# Threshold applied to the template matching
threshold = 0.55

# Apply the threshold to cv2 the template matching
loc = np.where( res >= threshold)

# Directory to save the matched templates (pattern)
s_dir = "s_img/"

# Counter to add in the name of the saved image
i = 1
for pt in zip(*loc[::-1]):
    # Draw a rectangle to area that satifies the condition
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 1)
    top_left = pt
    # Crop every matched templates (pattern)
    crop_img = img_rgb[top_left[1]:top_left[1] + h, top_left[0]:top_left[0]+w]
    bottom_right = (top_left[0] + w, top_left[1] + h)
    # Save the crop patterns for future use
    cv2.imwrite(s_dir+"crop_1_"+str(i)+".png", crop_img)
    # Label the coordinates for future use
    labeled_coordinates = ["crop_1_"+str(i), top_left[0], top_left[1], bottom_right[0], bottom_right[1]]
    # Add the coordinates in a list
    list_coordinates.append(labeled_coordinates)
    i += 1

cv2.imshow('template',template)
cv2.imshow('mathced',img_rgb)
cv2.waitKey(0)
cv2.destroyAllWindows()
EE2017
  • 49
  • 11
  • If the pattern is regular, then ImageMagick can do that. See https://imagemagick.org/Usage/crop/#crop_tile. Or write a Python loop and do the cropping using numpy slicing. – fmw42 Apr 30 '20 at 01:20
  • The pattern is one pot in the source image. I give the user a tool to crop a pot in the image which will be used as pattern to crop the other pots automatically. I will take a look at the ImageMagick and see what if I can do it with it. – EE2017 Apr 30 '20 at 11:03

0 Answers0