Reputation: 901
I thought I could do it myself!
So, I've been working on a project of mine, where I need to find an/multiple object(s) in an image (Currently, I am using simple template matching).
When an object is found, I want to remove pixels of that area and make the area transparent or fill it with any color.
For example, I have this Image (where I want to find the coke bottle cane
):-
After running Object detection script, I have:-
You can see the matched object inside the red rectangle!
Now, what I want to do is remove this rectangle area and make it transparent or fill it with any color!
I've tried many things, still trying but no luck. Here's what I have so far:
import numpy as np
import argparse
import imutils
import glob
import cv2
from matplotlib import pyplot as plt
ap = argparse.ArgumentParser()
ap.add_argument("-t", "--template", required=True, help="Path to template image")
ap.add_argument("-i", "--images", required=True,
help="Path to images where template will be matched")
ap.add_argument("-v", "--visualize",
help="Flag indicating whether or not to visualize each iteration")
args = vars(ap.parse_args())
def match_and_count(template, image):
img_rgb = cv2.imread(image)
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread(template,0)
w, h = template.shape[::-1]
res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where( res >= threshold)
f = set()
sensitivity = 100
for pt in zip(*loc[::-1]):
cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
# I want to make each rectangle transparent here
f.add((round(pt[0]/sensitivity), round(pt[1]/sensitivity)))
cv2.imwrite('multiple_objects.jpg',img_rgb)
print("Occurence of Object: %s" % len(f))
match_and_count(args["template"], args["images"])
If anyone could give a hint or a piece of code, that does the same. I'll be glad, thank you.
Upvotes: 4
Views: 1711
Reputation: 22954
You can use numpy slicing syntax to crop the box and then simply replace it with new color as:
replacement_color = np.array([20, 125, 89]) # any random color
for pt in zip(*loc[::-1]):
# cv2.rectangle(...)
img[pt[1]:pt[1] + h, pt[0]:pt[0]+w] = replacement_color
Or alternatively, you could have also used the cv2.rectangle
API to get the same results as:
replacement_color = np.array([20, 125, 89]) # any random color
for pt in zip(*loc[::-1]):
cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), replacement_color, -1)
You just need to pass the line_width param as -1
.
Upvotes: 6