【发布时间】:2020-08-06 21:29:12
【问题描述】:
我正在尝试确定拼图图像上拼图的位置。 我有
- 拼图图片(透明 png)
- 拼图板的图像,正确位置周围有白色轮廓
首先我提取图像 1 上的轮廓。并用它来绘制我的最终模板。 然后我将最终模板与拼图板匹配并保存一些结果图像。
以下是我得到的结果的一些示例 https://imgur.com/a/ZYyw7tU
在某些图像上,显然存在很多不匹配,对于某些图像,增加阈值将隐藏正确匹配,而某些不匹配将保留。
任何关于优化的提示或想法将不胜感激!
这是我的完整代码:
full_image = cv2.imread('puzzle_1.jpg')
piece = cv2.imread('piece_1.png', cv2.IMREAD_UNCHANGED)
partial_image = cv2.cvtColor(piece,cv2.COLOR_BGR2GRAY)
contours, hierarchy = cv2.findContours(partial_image.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
template = np.zeros((55, 55, 4), dtype=np.uint8)
cv2.drawContours(template, contours, -1, (255, 255, 255, 255),1)
hh, ww = template.shape[:2]
puzzleP = template[:,:,0:3]
alpha = template[:,:,3]
alpha = cv2.merge([alpha,alpha,alpha])
correlation = cv2.matchTemplate(full_image, puzzleP, cv2.TM_CCORR_NORMED, mask=alpha)
threshhold = 0.98
loc = np.where(correlation >= threshhold)
result = full_image.copy()
for pt in zip(*loc[::-1]):
cv2.rectangle(result, pt, (pt[0]+ww, pt[1]+hh), (0,0,255), 1)
print(pt)
cv2.imwrite('puzzle_piece.png', puzzleP)
cv2.imwrite('full_image_alpha.png', alpha)
cv2.imwrite('full_image_matches.jpg', result)
编辑: 这是两个文件(piece_1.png和puzzle_1.jpg)的示例(此示例有很多不匹配的地方) https://imgur.com/a/nGSXcNg
【问题讨论】:
-
请发布您的输入和模板图片
-
添加了puzzle_1.jpg和piece_1.png的链接
-
你为什么把每场比赛都画在你的阈值之上?没有意义。它不排除也高于您的阈值的小变化。除非您希望在多个地方找到模板,否则只需为每个输入图像绘制最佳匹配。如果由于拼图多次出现而预期多个匹配,那么您需要多次循环输入,每次都将前一个最佳匹配周围的区域涂黑,以便轻微的变化不会仍然匹配高于您的阈值,以便您将单个匹配项与非常接近的匹配项分开。
-
您还需要使模板的内部也透明。这样您就可以匹配拼图框架形状,我假设它出现在模板中。如果不这样做,那么由于亮度变化,模板内的纹理与图像中正确区域内的纹理不匹配,因此您将得到错误的匹配。另一种方法是将您的图像和模板转换为边缘并匹配它们。或者通过减去平均值并除以标准偏差来标准化您的图像和模板。但是,我认为后者不能很好地正常化。
-
阈值代码直接来自您为回答我之前的问题而编写的链接:stackoverflow.com/questions/61779288/…。我只会考虑绘制最佳匹配,但实际上最佳匹配通常不是最佳匹配,这让我感到困惑。匹配是在绘制矩形之前完成的,所以我看不出它会如何影响匹配?
标签: python opencv computer-vision