如何检测图像是否位于另一图像中?

2024-06-16 09:22:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图检测一个图像是否与另一个图像中的图像100%匹配,然后将变量设置为True。但是我读到的所有东西都没有结果,除了给出代码的一个特定线程

import cv2

method = cv2.TM_SQDIFF_NORMED

# Read the images from the file
small_image = cv2.imread('ran_away.png')
large_image = cv2.imread('pokemon_card.png')

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

# We want the minimum squared difference
mn,_,mnLoc,_ = cv2.minMaxLoc(result)

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

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

# Step 3: 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)

# The image is only displayed if we call this
cv2.waitKey(0)

然而,这打开了一个输出,并且做了我不想做的事情。我想做的就是检测图像是否在图像中,如果在图像中,则将其打印到控制台。在我的特殊情况下,我试图检测这个图像

Ran_away.png

在这张图中是什么

Pokemon_card.png

如果是,在控制台上打印口袋妖怪已经跑掉了


Tags: the图像imagepngmatchresultcv2method
2条回答

我使用相对较新的NumPy方法sliding_window_view找到了一个解决方案

Create a sliding window view into the array with the given window shape.

Also known as rolling or moving window, the window slides across all dimensions of the array and extracts subsets of the array at all window positions.

New in version 1.20.0.

注意:由于兼容性问题,我已在新的虚拟环境中安装了最新的NumPy版本

检查滑动窗口视图如何工作的简单测试:

import numpy as np
from numpy.lib.stride_tricks import sliding_window_view

t = np.array([[ [0,0,0], [1,1,1]],
              [ [2,2,2], [3,3,3]]])

x = np.array([[ [0,0,0],  [1,1,1],  [2,2,2],  [3,3,3]],
              [[10,10,10], [11,11,11], [12,12,12], [13,13,13]],
              [[20,20,20], [21,21,21], [22,22,22], [23,23,23]]])

x[1:3, 1:3, :] = t  # Copy t to x - it looks like there is a problem along edges

v = sliding_window_view(x, (2,2,3))

print(v-t)

结果开始于:

[[[[[[ 0  0  0]
     [ 0  0  0]]

这意味着t按预期从v的所有“窗口”中减去


为测试np.all添加以下命令:

print(np.where((v == t).all(axis=(3, 4, 5))))

输出为:

(array([1], dtype=int64), array([1], dtype=int64), array([0], dtype=int64))

如果沿轴3、4和5的所有元素都是True,则all(axis=(3, 4, 5))True
在上面的示例中,我们在索引[1,1]中找到了一个匹配项


以下是检测完美匹配的解决方案(使用NumPy):

import cv2
import numpy as np
from numpy.lib.stride_tricks import sliding_window_view

# Read the images from the file
small_image = cv2.imread('ran_away.png')
#small_image = cv2.imread('icon.png');
large_image = cv2.imread('pokemon_card.png')

v = sliding_window_view(large_image, small_image.shape)

match_idx = np.where((v == small_image).all(axis=(3, 4, 5)))

if len(match_idx[0]) > 0:
    row = match_idx[0][0]
    col = match_idx[1][0]

    cv2.rectangle(large_image, (col, row), (col+small_image.shape[1], row+small_image.shape[1]), (0, 255, 0), 2)

    cv2.imshow('large_image', large_image)
    cv2.waitKey()
    cv2.destroyAllWindows()

结果:
enter image description here

您的代码显示基本模板匹配。请阅读有关该主题的一些tutorial和有关^{}的文档,特别是了解不同的template match modes

我只能想到以下解决方案来处理您的任务:使用TM_SQDIFF_NORMED,而不是使用TM_SQDIFF,这样您可以在result中获得绝对值,而不是相对值:

  • 对于TM_SQDIFF_NORMED,最好的匹配总是在0.0附近的某个值,即使匹配不正确
  • 对于TM_SQDIFF,靠近0.0的某个值表示实际正确 匹配

现在,只需编写一个方法,进行模板匹配,并检测result的最小值是否低于0.0附近的某个阈值,比如10e-6。如果是,请打印出您想要的内容,如果不是,请执行其他操作:

import cv2


def is_template_in_image(img, templ):

    # Template matching using TM_SQDIFF: Perfect match => minimum value around 0.0
    result = cv2.matchTemplate(img, templ, cv2.TM_SQDIFF)

    # Get value of best match, i.e. the minimum value
    min_val = cv2.minMaxLoc(result)[0]

    # Set up threshold for a "sufficient" match
    thr = 10e-6

    return min_val <= thr


# Read template
template = cv2.imread('ran_away.png')

# Collect image file names
images = ['pokemon_card.png', 'some_other_image.png']

for image in images:
    if is_template_in_image(cv2.imread(image), template):
        print('{}: {}'.format(image, 'Pokemon has ran away.'))
    else:
        print('{}: {}'.format(image, 'Nothing to see here.'))

输出:

pokemon_card.png: Pokemon has ran away.
some_other_image.png: Nothing to see here.
                    
System information
                    
Platform:      Windows-10-10.0.19041-SP0
Python:        3.9.1
PyCharm:       2021.1.1
OpenCV:        4.5.2
                    

相关问题 更多 >