gpt4 book ai didi

python-3.x - OpenCV 无法将模板与图像匹配(matchTemplate)

转载 作者:太空宇宙 更新时间:2023-11-03 22:08:30 25 4
gpt4 key购买 nike

所以我有一个图像

image

和一个模板

template

我想在图像中找到模板图像,但我的代码没有找到任何东西。我试过缩小尺寸但仍然没有检测到。请帮我举个例子:

import cv2
import imutils
import glob, os
import numpy as np

image = cv2.imread("mainimage.png")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
h, w = gray.shape[:2]
for file in glob.glob("template.png"):
template = cv2.imread(file)
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
found = None
(tH, tW) = template.shape[:2]
cv2.imshow("Template", template)

for scale in np.linspace(1, 0.2, 20)[::-1]:
resized = imutils.resize(gray, width=int(gray.shape[1] * scale))
r = gray.shape[1] / float(resized.shape[1])

if resized.shape[0] < tH or resized.shape[1] < tW:
break
edged = cv2.Canny(resized, 50, 200)
result = cv2.matchTemplate(edged, template, cv2.TM_CCOEFF)
(_, maxVal, _, maxLoc) = cv2.minMaxLoc(result)

if found is None or maxVal > found[0]:
found = (maxVal, maxLoc, r)

(_, maxLoc, r) = found
(startX, startY) = (int(maxLoc[0] * r), int(maxLoc[1] * r))
(endX, endY) = (int((maxLoc[0] + tW) * r), int((maxLoc[1] + tH) * r))
cv2.rectangle(image, (startX, startY), (endX, endY), (0, 0, 255), 2)
cv2.imshow("Image", image)
cv2.waitKey(0)

最佳答案

您的代码大部分都不错。在您发布的代码中,您以错误的方式缩放。您正在缩小主图像而不是增大它。此外,您需要对模板和图像都进行 Canny。

在您发布的图像中,模板 (160x160) 大于主图像中的区域 (88x88)。如果缩放 mainimage,则缩放因子应为 1.818。缩放模板可能会快得多。

import cv2
# import imutils
import glob, os
import numpy as np

image = cv2.imread("mainimage.png")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
h, w = gray.shape[:2]
for file in glob.glob("template.png"):
template = cv2.imread(file)
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
found = None
(tH, tW) = template.shape[:2]
# cv2.imshow("Template", template)

tEdged = cv2.Canny(template, 50, 200)

for scale in np.linspace(1, 2, 20):
# resized = imutils.resize(gray, width=int(gray.shape[1] * scale))
resized = cv2.resize(gray, dsize = (0,0), fx = scale, fy = scale)

r = gray.shape[1] / float(resized.shape[1])

if resized.shape[0] < tH or resized.shape[1] < tW:
break
edged = cv2.Canny(resized, 50, 200)
result = cv2.matchTemplate(edged, tEdged, cv2.TM_CCOEFF)
(_, maxVal, _, maxLoc) = cv2.minMaxLoc(result)

if found is None or maxVal > found[0]:
found = (maxVal, maxLoc, r)

(_, maxLoc, r) = found
(startX, startY) = (int(maxLoc[0] * r), int(maxLoc[1] * r))
(endX, endY) = (int((maxLoc[0] + tW) * r), int((maxLoc[1] + tH) * r))
cv2.rectangle(image, (startX, startY), (endX, endY), (0, 0, 255), 2)

# cv2.imshow("Image", image)
cv2.imwrite('output.jpg', image)
# ~ cv2.waitKey(0)

在我的电脑上,这段代码需要 6 秒才能运行。

关键点匹配+单应性

作为替代方案,关键点匹配 + 单应性对尺度不敏感。在下面的代码中,dst 保存包含找到的模板的边界框的点。对我来说,以下代码在 0.06 秒内执行:

import cv2
# import imutils
import glob, os
import numpy as np
import time

image = cv2.imread("mainimage.png")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
h, w = gray.shape[:2]

MIN_MATCH_COUNT = 3

start_time = time.time()

for file in glob.glob("template.png"):
template = cv2.imread(file, 0)

patchSize = 16

orb = cv2.ORB_create(edgeThreshold = patchSize,
patchSize = patchSize)
kp1, des1 = orb.detectAndCompute(template, None)
kp2, des2 = orb.detectAndCompute(gray, None)

FLANN_INDEX_LSH = 6
index_params= dict(algorithm = FLANN_INDEX_LSH,
table_number = 6,
key_size = 12,
multi_probe_level = 1)
search_params = dict(checks = 50)

flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des1,des2,k=2)
# store all the good matches as per Lowe's ratio test.
good = []

for pair in matches:
if len(pair) == 2:
if pair[0].distance < 0.7*pair[1].distance:
good.append(pair[0])

print('len(good) ', len(good))
print('match %03d, min_match %03d, kp %03d' % (len(good), MIN_MATCH_COUNT, len(kp1)))
if len(good)>MIN_MATCH_COUNT:
src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0)
matchesMask = mask.ravel().tolist()
h,w = template.shape
pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)
dst = cv2.perspectiveTransform(pts,M)

# dst contains points of bounding box of template in image.
# draw a close polyline around the found template:
image = cv2.polylines(image,[np.int32(dst)],
isClosed = True,
color = (0,255,0),
thickness = 3,
linetype = cv2.LINE_AA)
else:
print( "Not enough matches are found - {}/{}".format(len(good), MIN_MATCH_COUNT) )
matchesMask = None

draw_params = dict(matchColor = (0,255,0), # draw matches in green color
singlePointColor = None,
matchesMask = matchesMask, # draw only inliers
flags = 2)

if len(good)>MIN_MATCH_COUNT:
output2 = cv2.drawMatches(template,kp1,gray,kp2,good,None,**draw_params)

print('elapsed time ', time.time()-start_time)
# cv2.imshow("Image", image)
cv2.imwrite('output_homography.jpg', image)
cv2.imwrite('output2.jpg', output2)

来自 cv2.drawMatches 函数的输出 2 enter image description here

关键点检测的重要参数之一是 patchSize。在代码中,我们对图像和模板都使用了 patchSize = 16。当您使 patchSize 更小时,您将获得更多关键点。你可以去的最小值是 2。但是当你变得太小时,你开始得到糟糕的匹配。我不确定如何找到最佳点。

关于python-3.x - OpenCV 无法将模板与图像匹配(matchTemplate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50641197/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com