0

I am trying to match a text with opencv and make the background of the provided image white and replace the text with a black rectangle.

import cv2
import numpy as np


img_rgb = cv2.imread('./image/10.jpg')
template = cv2.imread('./image/matchedTxt_106.jpg')
w, h = template.shape[:-1]

res = cv2.matchTemplate(img_rgb, template, cv2.TM_CCOEFF_NORMED)
threshold = .5
loc = np.where(res >= threshold)
for pt in zip(*loc[::-1]):  
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0, 0, 0), -1)

cv2.imwrite('result1.png', img_rgb)

Currently, I get the following result:

enter image description here

Find here my google colab example:

Notebook

The initial image 10.jpg looks like the following:

enter image description here

My template matchedTxt_106.jpg:

enter image description here

I would like to get the following result:

enter image description here

On the result image the location of the watermark is a black textbox and the background of the result image is white. The result image should have the same size as the previous image.

Any suggestions what I am doing wrong? Furthermore how can I get the coordinates of where the image text located on initial image?

I appreciate your replies!

Carol.Kar
  • 4,581
  • 36
  • 131
  • 264
  • 1
    What is the large image without marking and what is your template image? You can get the coordinates of the best location using cv2.minMaxLoc(). – fmw42 Sep 14 '21 at 15:40
  • @fmw42 Thx for your reply! Please find my update. – Carol.Kar Sep 14 '21 at 16:06
  • 1
    Sorry, I still do not understand. Have you reviewed the documentation on template matching for OpenCV and examples. You can find them by a Google search. You need a small image that matches something in your large image as a template image. The template image is searched to find its best matching location. It looks like you may want to find the text "LastSticker.com". Is that correct? Do you know where it is already as indicated by the black rectangle in the white background image? Or do you want to remove everything but that text and your output is the white and black image? Please explain – fmw42 Sep 14 '21 at 16:35
  • 1
    Please explain further. What are your input images? What further information do you have? What do you want for the output result? Please show and identify image/10.jpg and matchedTxt_106.jpg. Perhaps this post will help https://stackoverflow.com/questions/68693430/opencv2-matchtemplate-does-not-work-on-different-pictures-with-same-template/68694827#68694827 – fmw42 Sep 14 '21 at 16:40
  • 1
    If the black rectangle on white background is your final result, then once you have the template image, you can get its dimensions, w and h. Once you do your template matching, you can get the upper left corner x,y. Now you can create a white background image that is the same size as your input and draw a black filled rectangle on it at x,y,w,h. See np.full_like() to create a white image the size of the input image. – fmw42 Sep 14 '21 at 16:45
  • @fmw42 I only have the initial image and want to find the text laststicker.com on the initial image. Then I want to replace it with the black rectangle and do a white background. – Carol.Kar Sep 14 '21 at 16:56
  • Please show and identify image/10.jpg and matchedTxt_106.jpg. – fmw42 Sep 14 '21 at 19:54

1 Answers1

3

Your main issue is replacing width and height.

Replace w, h = template.shape[:-1] with:

h, w = template.shape[:-1]

In NumPy array shape, the height comes first.


Here is a code sample that results a black rectangle on white background:

import cv2
import numpy as np


img_rgb = cv2.imread('./image/10.png')  # ./image/10.jpg
template = cv2.imread('./image/matchedTxt_106.png')  # ./image/matchedTxt_106.jpg
h, w = template.shape[:-1]  # Height first.

img_bw = np.full(img_rgb.shape[:-1], 255, np.uint8)  # Initialize white image

res = cv2.matchTemplate(img_rgb, template, cv2.TM_CCOEFF_NORMED)
threshold = .5
loc = np.where(res >= threshold)
for pt in zip(*loc[::-1]):  
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0, 0, 0), -1)
    cv2.rectangle(img_bw, pt, (pt[0] + w, pt[1] + h), 0, -1)  # Draw black (filled) rectangle on img_bw

cv2.imwrite('result1.png', img_rgb)
cv2.imwrite('result_bw.png', img_bw)

Result:

result_bw.png:
enter image description here

result1.png:
enter image description here

Rotem
  • 30,366
  • 4
  • 32
  • 65