Python 带掩码的 OpenCV matchTemplate - 在所有位置找到匹配项
Python OpenCV matchTemplate with Masking - Found Matches at All Locations
问题:
我从 matchTemplate
收到的结果表明我在每个位置都有匹配值 1.0
。
预期结果:
我预计 results
中的一个位置比其他位置得分高得多。
代码:
def template_match(filename=base_name,
img_folder=trn_imgs_path,
templates=['wet_install.png',
'wet_install_cleaned.png',
'wet_install_tag.png',
'wet_install_tag_cleaned.png'],
template_path=template_path,
threshold=0.8,
save_dir=save_dir):
'''
Perform template matching on an input image using a few templates.
It draws bounding boxes on a copy of the original image.
Args:
filename (str): name of the file with the .svg extension
img_folder (str): path to folder containing the images
templates (list): list of template filenames to match against
template_path (str): path to folder containing the templates
threshold (float): the threshold for a match from template matching
save_dir (str): path to folder to save results
'''
print('Working on file: {}.png'.format(filename))
# load the original BGR image
img_rgb = cv2.imread(img_folder + filename + '.png')[5143:5296, 15169:15368] # TODO(mtu): Don't keep these indices here!
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
img_gray = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 1)
# loop over each template
colors = [(0,0,255), (0,255,0), (255,255,0), (255,0,255)]
for itemp in range(len(templates)):
template_name = templates[itemp]
print('Using Template: {}'.format(template_name))
# load the template as grayscale and get its width and height
template = cv2.imread(template_path + '{}'.format(template_name), 0)
height, width = template.shape[:2]
template = cv2.adaptiveThreshold(template, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 1)
temp_mask = cv2.adaptiveThreshold(template, 1, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 115, 1)
# do template matching using grayscale image and find points above theshold
results = cv2.matchTemplate(image=img_gray, templ=template, method=cv2.TM_CCORR_NORMED, mask=temp_mask)
loc = np.where(results >= threshold)
# draw rectangles on points above threshold on RGB image
for pt in zip(*loc[::-1]):
cv2.rectangle(img_rgb, pt, (pt[0] + width, pt[1] + height), colors[itemp%len(colors)], 5)
# save the file with bounding boxes drawn on
filename = save_dir + '{}_found.png'.format(filename)
print('Saving bounding boxes to: {}'.format(filename))
cv2.imwrite(filename, img_rgb)
评论:
- Debug output 显示了
img_gray
、template
和 temp_mask
的视觉效果
img_gray
只是 template
顶部有 10 行额外的白色填充像素
template
和temp_mask
是相同的形状和类型
- Saved output image
反转 img_gray
和 template
修复了错误。
我使用的比较指标是 cv2.TM_CCORR_NORMED
。这是通过取 img_gray
和 template
的点积来实现的,其中二进制 numpy 数组 temp_mask
的值为 1
.
在我的示例图像中,我想将 template
中的黑色像素与 img_gray
中的黑色像素进行匹配,但是黑色的像素值为 0
。因此,我想要检测的位置的点积很低。
通过反转 img_gray
和 template
,我将 template
中的白色像素与 img_gray
中的白色像素进行匹配。由于白色具有像素值 255
,因此白色与白色、模板与图像的点积在我要检测的位置变高。
问题:
我从 matchTemplate
收到的结果表明我在每个位置都有匹配值 1.0
。
预期结果:
我预计 results
中的一个位置比其他位置得分高得多。
代码:
def template_match(filename=base_name,
img_folder=trn_imgs_path,
templates=['wet_install.png',
'wet_install_cleaned.png',
'wet_install_tag.png',
'wet_install_tag_cleaned.png'],
template_path=template_path,
threshold=0.8,
save_dir=save_dir):
'''
Perform template matching on an input image using a few templates.
It draws bounding boxes on a copy of the original image.
Args:
filename (str): name of the file with the .svg extension
img_folder (str): path to folder containing the images
templates (list): list of template filenames to match against
template_path (str): path to folder containing the templates
threshold (float): the threshold for a match from template matching
save_dir (str): path to folder to save results
'''
print('Working on file: {}.png'.format(filename))
# load the original BGR image
img_rgb = cv2.imread(img_folder + filename + '.png')[5143:5296, 15169:15368] # TODO(mtu): Don't keep these indices here!
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
img_gray = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 1)
# loop over each template
colors = [(0,0,255), (0,255,0), (255,255,0), (255,0,255)]
for itemp in range(len(templates)):
template_name = templates[itemp]
print('Using Template: {}'.format(template_name))
# load the template as grayscale and get its width and height
template = cv2.imread(template_path + '{}'.format(template_name), 0)
height, width = template.shape[:2]
template = cv2.adaptiveThreshold(template, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 1)
temp_mask = cv2.adaptiveThreshold(template, 1, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 115, 1)
# do template matching using grayscale image and find points above theshold
results = cv2.matchTemplate(image=img_gray, templ=template, method=cv2.TM_CCORR_NORMED, mask=temp_mask)
loc = np.where(results >= threshold)
# draw rectangles on points above threshold on RGB image
for pt in zip(*loc[::-1]):
cv2.rectangle(img_rgb, pt, (pt[0] + width, pt[1] + height), colors[itemp%len(colors)], 5)
# save the file with bounding boxes drawn on
filename = save_dir + '{}_found.png'.format(filename)
print('Saving bounding boxes to: {}'.format(filename))
cv2.imwrite(filename, img_rgb)
评论:
- Debug output 显示了
img_gray
、template
和temp_mask
的视觉效果 img_gray
只是template
顶部有 10 行额外的白色填充像素template
和temp_mask
是相同的形状和类型- Saved output image
反转 img_gray
和 template
修复了错误。
我使用的比较指标是 cv2.TM_CCORR_NORMED
。这是通过取 img_gray
和 template
的点积来实现的,其中二进制 numpy 数组 temp_mask
的值为 1
.
在我的示例图像中,我想将 template
中的黑色像素与 img_gray
中的黑色像素进行匹配,但是黑色的像素值为 0
。因此,我想要检测的位置的点积很低。
通过反转 img_gray
和 template
,我将 template
中的白色像素与 img_gray
中的白色像素进行匹配。由于白色具有像素值 255
,因此白色与白色、模板与图像的点积在我要检测的位置变高。