python中模板匹配后如何确定图像上的像素坐标?
How to determine pixel coordinates on an image after template matching in python?
我有一个 3D 电影图像,本身就有星星般的人物。我有一个形状为 (21,21,1) 的模板,它有助于找到图像上的初始点(矩形)。我已经完成了块匹配部分,并且能够确定一些匹配的坐标,由于图像的像素强度不同,这些坐标有时是正确的,有时是不正确的。图像和模板都是灰色的。以下是我的代码、结果和预期结果。任何帮助(想法)解决这个问题会被承认
模板匹配代码
image = cv2.imread('45_gray.jpg', 0 )
template = cv2.imread('45tmpl.jpg', 0)
(tW, tH) = template.shape[::-1]
result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
#print(result)
threshold = 0.8
(yCoords, xCoords) = np.where(result >= threshold)
clone = image.copy()
#print(yCoords, xCoords)
for (x, y) in zip(xCoords, yCoords):
# draw the bounding box on the image
cv2.rectangle(clone, (x, y), (x + tW, y + tH),(255, 247, 263), 3)
# show our output image *before* applying non-maxima suppression
#cv2.imshow("Before NMS", clone)
#cv2.waitKey(0)
cv2.imwrite('output match.jpg', clone)
我认为这个模板匹配在这里不会很有效。正如您可能注意到的,在输入图像中存在从左下角到右上角的渐变,图像似乎在那个方向上淡出。因此,在左上角,为了使模板匹配有效地工作,功能并不明显。我建议首先使用 adaptiveThreshold 技术将此图像转换为二值图像:
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_adaptive = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 15, 5)
一旦你有了看起来一致的双色图像,它不包含任何渐变,你可以遵循模板匹配路径,或者在这种情况下我选择遵循检测直线然后处理的替代方法他们的交叉点作为兴趣点。
现在可以使用 cv2.HoughLinesP
来检测线条,但它有自己的一组参数,需要对其进行适当调整才能使其正常工作,所以我简单地计算了每行中存在的 while 像素数和列分别过滤局部最大值点。也就是说,我选择了白色像素数多于相邻行的行,并且对每一列也做了同样的处理。
import cv2
import numpy as np
from scipy.signal import argrelextrema
img = cv2.imread("/home/anmol/Downloads/x5JQF.jpg")
img = cv2.resize(img, None, fx=0.4, fy=0.4)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_adaptive = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 5)
cv2.imwrite("./debug.png", img_adaptive)
row_white_pixel_count = np.array([np.count_nonzero(img_adaptive[i,:]) for i in range(img_adaptive.shape[0])])
col_white_pixel_count = np.array([np.count_nonzero(img_adaptive[:,i]) for i in range(img_adaptive.shape[1])])
row_maxima = argrelextrema(row_white_pixel_count, np.greater, order=50)[0]
col_maxima = argrelextrema(col_white_pixel_count, np.greater, order=50)[0]
all_intersection_coords = []
for row_idx in row_maxima:
for col_idx in col_maxima:
all_intersection_coords.append((col_idx, row_idx))
for coord in all_intersection_coords:
img = cv2.circle(img, coord, 10, (0, 240, 0), 2)
我有一个 3D 电影图像,本身就有星星般的人物。我有一个形状为 (21,21,1) 的模板,它有助于找到图像上的初始点(矩形)。我已经完成了块匹配部分,并且能够确定一些匹配的坐标,由于图像的像素强度不同,这些坐标有时是正确的,有时是不正确的。图像和模板都是灰色的。以下是我的代码、结果和预期结果。任何帮助(想法)解决这个问题会被承认 模板匹配代码
image = cv2.imread('45_gray.jpg', 0 )
template = cv2.imread('45tmpl.jpg', 0)
(tW, tH) = template.shape[::-1]
result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
#print(result)
threshold = 0.8
(yCoords, xCoords) = np.where(result >= threshold)
clone = image.copy()
#print(yCoords, xCoords)
for (x, y) in zip(xCoords, yCoords):
# draw the bounding box on the image
cv2.rectangle(clone, (x, y), (x + tW, y + tH),(255, 247, 263), 3)
# show our output image *before* applying non-maxima suppression
#cv2.imshow("Before NMS", clone)
#cv2.waitKey(0)
cv2.imwrite('output match.jpg', clone)
我认为这个模板匹配在这里不会很有效。正如您可能注意到的,在输入图像中存在从左下角到右上角的渐变,图像似乎在那个方向上淡出。因此,在左上角,为了使模板匹配有效地工作,功能并不明显。我建议首先使用 adaptiveThreshold 技术将此图像转换为二值图像:
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_adaptive = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 15, 5)
一旦你有了看起来一致的双色图像,它不包含任何渐变,你可以遵循模板匹配路径,或者在这种情况下我选择遵循检测直线然后处理的替代方法他们的交叉点作为兴趣点。
现在可以使用 cv2.HoughLinesP
来检测线条,但它有自己的一组参数,需要对其进行适当调整才能使其正常工作,所以我简单地计算了每行中存在的 while 像素数和列分别过滤局部最大值点。也就是说,我选择了白色像素数多于相邻行的行,并且对每一列也做了同样的处理。
import cv2
import numpy as np
from scipy.signal import argrelextrema
img = cv2.imread("/home/anmol/Downloads/x5JQF.jpg")
img = cv2.resize(img, None, fx=0.4, fy=0.4)
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_adaptive = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 5)
cv2.imwrite("./debug.png", img_adaptive)
row_white_pixel_count = np.array([np.count_nonzero(img_adaptive[i,:]) for i in range(img_adaptive.shape[0])])
col_white_pixel_count = np.array([np.count_nonzero(img_adaptive[:,i]) for i in range(img_adaptive.shape[1])])
row_maxima = argrelextrema(row_white_pixel_count, np.greater, order=50)[0]
col_maxima = argrelextrema(col_white_pixel_count, np.greater, order=50)[0]
all_intersection_coords = []
for row_idx in row_maxima:
for col_idx in col_maxima:
all_intersection_coords.append((col_idx, row_idx))
for coord in all_intersection_coords:
img = cv2.circle(img, coord, 10, (0, 240, 0), 2)