cv2在另一张图片中找图片

Cv2 finding pictures in another picture

一张大图(300*300像素)分为3个区域。 2 个小的(AAA.png 和 BBB.png)是大图的一部分。

3-areas.png

AAA.png

BBB.png

我想知道它们位于哪些区域,即在大图中找到小图。 理想的输出是:"AAA.png is in the left"; "BBB.png is in the right".

我有这些代码 运行:

import cv2, os
import numpy as np

big_pic = cv2.imread("c:\TEM\3-areas.png")

left_area = big_pic[0:300, 0:100]   # [y,y1 : x,x1]
mid_area = big_pic[0:300, 100:200]
right_area = big_pic[0:300, 200:300]

AAA = cv2.imread('C:\TEM\AAA.png')
AAA_res = cv2.matchTemplate(left_area,AAA,cv2.TM_CCOEFF_NORMED)

threshold = 0.99
AAA_loc = np.where(AAA_res >= threshold)
a_x_cor = list(AAA_loc[0])
a_y_cor = list(AAA_loc[1])
print a_x_cor, a_y_cor

BBB = cv2.imread('C:\TEM\BBB.png')
BBB_res = cv2.matchTemplate(right_area,BBB,cv2.TM_CCOEFF_NORMED)

BBB_loc = np.where(BBB_res >= threshold)
b_x_cor = list(BBB_loc[0])
b_y_cor = list(BBB_loc[1])

print b_x_cor, b_y_cor

我想通过 for 循环来简化它。我尝试了什么:

big_pic = cv2.imread("c:\TEM\3-areas.png")

list_of_areas = {
left : [0,300, 0,100],
mid : [0,300, 100,200],
right : [0,300, 200,300]}

small_picture_folder = "C:\TEM\"
small_pictures = []

root, dirs, files = os.walk(small_picture_folder).next()

for path, subdirs, files in os.walk(root):
    for f in files:
        if ""AAA"" in f or ""BBB"" in f:
           small_pictures.append(small_picture_folder + f)

for key, value in list_of_areas.iteritems():
    for y,y1,x,x1 in value:
        target_area = big_pic[y:y1, x:x1]

"for y,y1,x,x1 in value:"行给出错误:"TypeError: 'int' object is not iterable."

实现它的最佳方法是什么?谢谢。

这是检测多个模板和裁剪 ROI 的方法

import cv2
import numpy as np
templates = []
templ_shapes = []
threshold = 0.9
# get 1st template
temp1 =cv2.imread("YourImagePath1.png",cv2.IMREAD_GRAYSCALE)
templates.append(temp1)
templ_shapes.append(temp1.shape[:: -1])

# get 2nd template
temp2 =cv2.imread("YourImagePath2.png",cv2.IMREAD_GRAYSCALE)
templates.append(temp2)
templ_shapes.append(temp2.shape[:: -1])

# templ_shapes contains (width and height) dimensions of your templates
# so use them to display bounding box

# detect and get ROI
target =cv2.imread("YourImage_Target_Path.png",cv2.IMREAD_GRAYSCALE)
count = 0
for template in templates:
result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
loc = np.where(result >= threshold)
for pt in zip(*loc[::-1]):
    # pt is the top left corner of the template location so pt[0] + templ_shapes[count][0] is the X bottom right ...
    # templ_shapes[count][0] is the width and templ_shapes[count][1] is height
    cv2.rectangle(target, pt, (pt[0] + templ_shapes[count][0], pt[1] + templ_shapes[count][1]), (0, 0, 255), 2)
    roi = target[pt[1]:pt[1] + templ_shapes[count][1] ,pt[0] :pt[0] +templ_shapes[count][0]] 
count+=1

您尝试做的是一种对象检测算法。 看看这个 opencv 教程。 https://docs.opencv.org/2.4/doc/tutorials/features2d/feature_homography/feature_homography.html 为了提高速度,请尝试用 orb keypoint 替换 Surf keypoint(对于您的用例,它可能已经足够好了,(如果您这样做,请不要忘记将范数从 L2 修改为 Hamming )) 这是你的问题的概括。 亲切的问候

在你的外循环中,迭代字典条目

for key, value in list_of_areas.iteritems():

value 是一个包含四个整数的列表,例如[0, 300, 0, 100]。因此,当您现在尝试使用

迭代此列表时
for (...) in value:

您将进行四次迭代,并且在每次迭代中,一次只会有一个列表项 "returned"。但是现在,您尝试通过

将这个"returned",单个整数值同时分配给四个变量
for y, y1, x, x1 in value:

因此错误!因此,从我的角度来看,最简单的解决方案是跳过内部循环,直接将 value 中的所有项目分配给您的四个变量,如下所示:

for key, value in list_of_areas.iteritems():
    y, y1, x, x1 = value
    target_area = big_pic[y:y1, x:x1]

希望对您有所帮助!