python - 在另一个图像上匹配轮廓或绘制 (png) 轮廓
问题描述
假设我在图像上找到了轮廓。在图像 2 上找到此轮廓位置的最佳方法是什么?
我看到两个选项:要么我用白线绘制轮廓并匹配图像 2 上的图像,要么我以某种方式(这甚至可能吗?)直接匹配图像 2 上的轮廓。
轮廓内的内容是完全随机的,但是假设我可以模板匹配具有透明度的图像,则使用白色 1px 线绘制的图像 1 的轮廓将是完全匹配的。
以下是找到、绘制和保存的轮廓的示例图像(图像 1)和我需要在其中定位图像 1 的图像(图像 2)。 https://imgur.com/a/MNQ6aNr
无需先绘制和保存就可以找到轮廓,但我认为匹配绘制的轮廓更直接。
谢谢
编辑:
这是我的完整代码。它需要一个 full_image 和一个片段,它将在完整图像上匹配。最后它导出一些结果。
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)
这是一个运行良好的结果和一个无效的结果 https://imgur.com/a/ZYyw7tU
任何有关改进的提示将不胜感激!
解决方案
您可以在 Python/OpenCV 中使用带有掩码图像的 matchTemplate 来忽略模板的区域。因此,如果您有一个透明模板,则提取 alpha 通道并将其用作蒙版,使用模板 BGR 通道作为 matchTemplate 中的模板图像。看
https://docs.opencv.org/4.1.1/df/dfb/group__imgproc__object.html#ga586ebfb0a7fb604b35a23d85391329be
推荐阅读
- angular - 在 Angular RxJS 可观察方法中等待 Promise 结果
- javascript - 如何在节点应用程序的异步函数中执行 MySQL 查询
- android - 是否可以用 USB 连接两台设备并在一台设备上运行 adb 命令
- r - 如何将ggridges中的部分密度曲线与构面一起填充
- delphi - 在 VCL 中连接 SearchBox 和 ListBox
- javascript - 我需要一个包作为 devDependency 和依赖项
- c++ - asio::io_context 和 asio::thread_pool 有什么区别?
- javascript - Reactjs - 使用 React Hooks 获取 div/图像的高度
- build.gradle - Gradle 错误:在根项目中找不到任务“清理”
- android - 我想在 Node Js 服务器中上传图片时添加 ID