我有两个面,一个大Python的OpenCV的:使用matchTemplate
我试图将它们视为灰度图像,以适应template matching tutorial这些表面。
我需要更新教程以在x和y中独立缩放,我已经完成了这个工作,但添加了一个额外的循环。我的代码是:
import pandas as pd
import numpy as np
import cv2
import matplotlib.pyplot as plt
import matplotlib.patches as patches
# If True shows each iteration of the template matching
Visualise = True
# Load in image and template
image = pd.read_excel('TemplateMatching_exampleData.xlsx',sheetname="radial_template").as_matrix().astype(np.float32)
template = pd.read_excel('TemplateMatching_exampleData.xlsx',sheetname="radial_image").as_matrix().T.astype(np.float32)
# Save a raw copy of the template
template_raw = template
# Rescale the template to approximate the same range in values as the image
template = template - np.mean(template)
template = (template/np.max(template)) * np.max(image)
# Get the height and width of the template
(tH, tW) = template.shape[:2]
# initialize the bookkeeping variable to keep track of the matched region
found = None
# If visualise = True then initialise the figure to show the iteration
if Visualise:
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
# loop over the scales of the image
for scale_width in np.linspace(0.1, 2, 20):
for scale_height in np.linspace(0.1, 3, 20)[::-1]:
# resize the image according to the scale, and keep track
# of the ratio of the resizing
resized = cv2.resize(image, (int(image.shape[0] * scale_height), int(image.shape[1] * scale_width)))
r_h = image.shape[0]/float(resized.shape[0])
r_w = image.shape[1]/float(resized.shape[1])
# if the resized image is smaller than the template, then break
# from the loop
if resized.shape[0] < tH or resized.shape[1] < tW:
break
# apply template matching to find the template in the image
result = cv2.matchTemplate(resized, template, cv2.TM_CCOEFF)
(_, maxVal, _, maxLoc) = cv2.minMaxLoc(result)
# check to see if the iteration should be visualized
if Visualise:
ax1.clear()
ax1.imshow(resized)
ax1.add_patch(patches.Rectangle((maxLoc[0], maxLoc[1]), tW, tH, fill=False, edgecolor = 'red'))
plt.show()
plt.draw()
plt.pause(0.05) # fig1.waitforbuttonpress()
# if we have found a new maximum correlation value, then update
# the bookkeeping variable
if found is None or maxVal > found[0]:
found = (maxVal, maxLoc, r_w, r_h, scale_width, scale_height)
# unpack the bookkeeping varaible and compute the (x, y) coordinates
# of the bounding box based on the resized ratio
(_, maxLoc, r_w, r_h, scale_width, scale_height) = found
(startX, startY) = (int(maxLoc[0] * r_w), int(maxLoc[1] * r_h))
(endX, endY) = (int((maxLoc[0] + tW) * r_w), int((maxLoc[1] + tH) * r_h))
# draw a bounding box around the detected result and display the image
figure = plt.figure()
ax1 = figure.add_subplot(111)
ax1.imshow(image)
ax1.add_patch(patches.Rectangle((startX,startY), endX-startX, endY-startY, fill=False, edgecolor = 'red'))
plt.show()
plt.draw()
# show the matching image segment and template together
plt.figure()
plt.subplot(121)
plt.imshow(image[startX:endX, startY:endY])
plt.title('Image')
plt.subplot(122)
plt.imshow(template)
plt.title('Template')
但是什么我发现的是,“最佳组合”是在最大scale_width
值总是发现,不管是什么我将该值设置为是,但我想不通为什么。我猜这是衡量体质如何的结果,但我对cv2.matchTemplate
了解不多,因此我一直在苦苦思索这几天。
请你能帮我解决我的代码吗?
我已将我的数据从我的Excel文件复制到this GoogleDocs document。
1.它可能会更好用标准差(简单地'numpy.std(阵列)')不仅仅是由最大规模来划分;通过std dev移动均值和潜水给你一个0均值和单位标准dev的分布。 2.您应该缩放模板和图像以获得相似的分布。 3.您可以共享Excel数据在公共谷歌片或类似的,或缩放的灰阶值恰好浮子0 UINT8 0和1之间或之间和255,并将它们保存为OpenCV的'imwrite()'和公布这些灰度图像为我们加载。 –
谢谢,我在主帖中添加了数据链接 – jlt199
查看电子表格中的值,您是否实际缩放了'image'或仅仅是'template'?因为由'max'被划分后,你的模板将有'1',而你的'image'有像一个最大值'10000',所以你不会得到任何接近的比赛的最大值。请尝试按比例两者,无论是与标准方差就像我提到的,甚至只是天真地转移/他们两个大规模进入0和1,看看你是否得到比赛的方式。因为否则,只要关闭该教程并扩展您的模板应该会相对较好。 –