【问题标题】:How do I find the percent chance that an image is in another image?我如何找到一个图像在另一个图像中的百分比?
【发布时间】:2021-08-20 04:25:47
【问题描述】:

我正在尝试获取图像在 OpenCV 中的另一个图像中的百分比。

这是我正在比较的图像:

]2

这是我的代码:

import cv2
import numpy as np

large_image = cv2.imread(r'Directory here')

#Cropping the image so that it's easier to compare
height = large_image.shape[0]
width = large_image.shape[1]
large_image = large_image[5:height-173,260:width-25]

small_image = cv2.imread(r'Directory here')

method = cv2.TM_SQDIFF_NORMED

# Read the images from the file

result = cv2.matchTemplate(small_image, large_image, method)

#BELOW IS ONLY IF YOU WANT TO SEE A RECTANGLE AROUND THE IMAGE
# We want the minimum squared difference
mn,_,mnLoc,_ = cv2.minMaxLoc(result)

# Draw the rectangle:
# Extract the coordinates of our best match
MPx,MPy = mnLoc

# Get the size of the template. This is the same size as the match.
trows,tcols = small_image.shape[:2]

# Draw the rectangle on large_image
cv2.rectangle(large_image, (MPx,MPy),(MPx+tcols,MPy+trows),(0,0,255),2)

# Display the original image with the rectangle around the match.
cv2.imshow('output',large_image)
cv2.waitKey(0)

OpenCV 甚至可以做到这一点吗?

【问题讨论】:

  • 使用 TM_CCOEFF_NORMED 并遵循 HansHirse 下面关于屏蔽的说明。这种方法理论上应该生成一个浮动图像,其范围应该在 -1 和 1 之间,其中 1 是完美匹配,尽管通常在 0 和 1 之间。找到图像中的最大值并乘以 100 以获得匹配百分比。
  • 你能包含代码吗,我不知道把“cv2.TM_CCOEFF_NORMED”放在哪里。对不起,如果这听起来很愚蠢,但我不擅长 OpenCV。
  • method = cv2.TM_SQDIFF_NORMED 替换为method = cv2.TM_CCOEFF_NORMED 参见docs.opencv.org/4.1.1/df/dfb/…
  • 我尝试使用 HansHirse 的代码将“cv2.TM_CCOEFF_NORMED”替换为“cv2.TM_SQDIFF_NORMED”,但它与“cv2.TM_SQDIFF_NORMED”的工作方式不同。
  • 我希望你使用 method = cv2.TM_CCOEFF_NORMED 完美匹配为 1。另一个完美匹配为 0。所以它们的工作方式不同。如果你想得到一个百分比。使用我所说的乘以 100。

标签: python python-3.x opencv template-matching


【解决方案1】:

总的来说,您的方法和代码是正确的。缺少什么:请注意,您的模板(小图像)具有一定的透明度,因此是 Alpha 通道。要保留那个,请在相应的cv2.imread 调用中使用cv2.IMREAD_UNCHANGED 标志。现在,您的模板的背景是用黑白像素填充的,这会导致在将像素与实际图像(大图)匹配时出现错误的结果。

幸运的是,cv2.matchTemplate 有一个mask 参数。因此,要匹配的像素仅限于该掩码所描述的像素。太好了,这正是我们从您模板的 Alpha 通道中得到的。

这里有一些(大量)修改和缩短的代码:

import cv2

# Read images; preserve alpha channel in template
image = cv2.imread('image.png')
templ = cv2.imread('template.png', cv2.IMREAD_UNCHANGED)

# Actual template matching; use alpha channel of template as mask
result = cv2.matchTemplate(image, templ[..., :3], cv2.TM_SQDIFF_NORMED,
                           mask=templ[..., 3])

# Get location of best match, and draw rectangle
mpx, mpy = cv2.minMaxLoc(result)[2]
h, w = templ.shape[:2]
cv2.rectangle(image, (mpx, mpy), (mpx + w, mpy + h), (0, 0, 255), 2)

# Output
cv2.imshow('image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

而且,这就是结果,我猜应该是预期的:

顺便说一句:注意cv2.matchTemplate的参数。第一个参数是实际图像(大图),第二个参数是模板(小图)。这是在您的代码中切换的!不使用遮罩时,顺序无效,但提供遮罩时,形状必须与模板相同,并自动对照第二个参数的形状检查!

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.19042-SP0
Python:        3.9.6
PyCharm:       2021.2
OpenCV:        4.5.3
----------------------------------------

【讨论】:

    猜你喜欢
    • 2011-01-29
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 2018-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多