Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python OpenCV匹配图像上的多帧_Python_Opencv_Opencv3.0 - Fatal编程技术网

Python OpenCV匹配图像上的多帧

Python OpenCV匹配图像上的多帧,python,opencv,opencv3.0,Python,Opencv,Opencv3.0,我是OpenCV的新手,我想找到一个解决方案,在某个图像上找到多个带有文本的图像。将来我需要这些东西来认可 首先,我有一个搜索模板的图像帧。它看起来像一个中心透明的框架。 我尝试了很多样本来匹配模板,但它们只给出了一个搜索结果:只找到了第一个或第二个项目,但我需要所有这些 请帮我想办法解决这个问题 框架模板: 场景: 代码: 结果图像: 对于模板匹配算法,每当您找到相似度的最大值时,您应该将创建的像素设置为零,如果不这样做,就像在每次迭代中通过cv2.minMaxLoc函数找到相同的像素一样

我是OpenCV的新手,我想找到一个解决方案,在某个图像上找到多个带有文本的图像。将来我需要这些东西来认可

首先,我有一个搜索模板的图像帧。它看起来像一个中心透明的框架。 我尝试了很多样本来匹配模板,但它们只给出了一个搜索结果:只找到了第一个或第二个项目,但我需要所有这些

请帮我想办法解决这个问题

框架模板:

场景:

代码:

结果图像:


对于模板匹配算法,每当您找到相似度的最大值时,您应该将创建的像素设置为零,如果不这样做,就像在每次迭代中通过
cv2.minMaxLoc
函数找到相同的像素一样

您可能会遇到需要将最大像素周围的小区域设置为零以获得最佳结果的情况

我为您的问题编写了一个简单的代码,但在这种情况下,模板匹配似乎不是很好

import cv2
import numpy as np

method = cv2.TM_CCORR_NORMED
threshold = 0.7


img_main = cv2.imread('images/garden.jpg')
template = cv2.imread('images/frame_trans.png', cv2.IMREAD_GRAYSCALE)
template_gray = template

img_main_gray = cv2.cvtColor(img_main, cv2.COLOR_BGR2GRAY)
w, h = template.shape[::-1]

res = cv2.matchTemplate(img_main_gray, template_gray, method)

cv2.normalize(res, res, 0., 1., cv2.NORM_MINMAX)
cv2.threshold(res, threshold, 1, cv2.THRESH_TOZERO)

i = 0

border=45  # I have added this line to control the area that must be zero
while i < 20:
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    print(max_val)
    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
        top_left = min_loc
    else:
        top_left = max_loc

    if max_val > threshold:
#         print(top_left)
        bottom_right = (top_left[0] + w, top_left[1] + h)
#         cv2.circle(img_main,max_loc,5,(0,0,255),1)
        cv2.rectangle(img_main, top_left, bottom_right, (0, 0, 255), 5)
        cv2.floodFill(img_main_gray, None, top_left, 0, 0.1, 1.0)
    i += 1
    res[max_loc[1]-border:max_loc[1]+border,max_loc[0]-border:max_loc[0]+border]=0  # set zero the max loc

img_main=cv2.cvtColor(img_main,cv2.COLOR_BGR2RGB)
import matplotlib.pyplot as plt
plt.figure(figsize=(10,12))
plt.imshow(res)
plt.figure(figsize=(10,12))
plt.imshow(img_main)
导入cv2
将numpy作为np导入
方法=cv2.TM\u CCORR\u标准
阈值=0.7
img_main=cv2.imread('images/garden.jpg'))
模板=cv2.imread('images/frame\u trans.png',cv2.imread\u灰度)
模板\灰色=模板
img\u main\u gray=cv2.CVT颜色(img\u main,cv2.COLOR\u BGR2GRAY)
w、 h=模板。形状[:-1]
res=cv2.matchTemplate(img_main_gray,template_gray,method)
cv2.标准化(res,res,0.,1.,cv2.标准值_最小值)
cv2.阈值(分辨率,阈值,1,cv2.阈值至零)
i=0
border=45#我添加了这条线来控制必须为零的区域
而我<20:
最小值,最大值,最小位置,最大位置=cv2。最小最大位置(res)
打印(最大值)
如果[cv2.TM_SQDIFF,cv2.TM_SQDIFF_NORMED]中的方法:
左上=最小位置
其他:
左上=最大位置
如果最大值>阈值:
#打印(左上角)
右下=(左上[0]+w,左上[1]+h)
#cv2.圆圈(img_主,最大位置,5,(0,0255),1)
cv2.矩形(img_main,左上,右下,(0,0,255),5)
cv2.洪水填充(img_主灰色,无,左上角,0,0.1,1.0)
i+=1
res[max_loc[1]-边界:max_loc[1]+边界,max_loc[0]-边界:max_loc[0]+边界]=0#将max loc设置为零
img_main=cv2.cvt颜色(img_main,cv2.COLOR\u BGR2RGB)
将matplotlib.pyplot作为plt导入
plt.图(figsize=(10,12))
plt.imshow(res)
plt.图(figsize=(10,12))
plt.imshow(img_主)

对于模板匹配算法,每当您找到相似度的最大值时,您应该将创建的像素设置为零,如果不这样做,就像在每次迭代中通过
cv2.minMaxLoc
函数找到相同的像素一样

您可能会遇到需要将最大像素周围的小区域设置为零以获得最佳结果的情况

我为您的问题编写了一个简单的代码,但在这种情况下,模板匹配似乎不是很好

import cv2
import numpy as np

method = cv2.TM_CCORR_NORMED
threshold = 0.7


img_main = cv2.imread('images/garden.jpg')
template = cv2.imread('images/frame_trans.png', cv2.IMREAD_GRAYSCALE)
template_gray = template

img_main_gray = cv2.cvtColor(img_main, cv2.COLOR_BGR2GRAY)
w, h = template.shape[::-1]

res = cv2.matchTemplate(img_main_gray, template_gray, method)

cv2.normalize(res, res, 0., 1., cv2.NORM_MINMAX)
cv2.threshold(res, threshold, 1, cv2.THRESH_TOZERO)

i = 0

border=45  # I have added this line to control the area that must be zero
while i < 20:
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    print(max_val)
    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
        top_left = min_loc
    else:
        top_left = max_loc

    if max_val > threshold:
#         print(top_left)
        bottom_right = (top_left[0] + w, top_left[1] + h)
#         cv2.circle(img_main,max_loc,5,(0,0,255),1)
        cv2.rectangle(img_main, top_left, bottom_right, (0, 0, 255), 5)
        cv2.floodFill(img_main_gray, None, top_left, 0, 0.1, 1.0)
    i += 1
    res[max_loc[1]-border:max_loc[1]+border,max_loc[0]-border:max_loc[0]+border]=0  # set zero the max loc

img_main=cv2.cvtColor(img_main,cv2.COLOR_BGR2RGB)
import matplotlib.pyplot as plt
plt.figure(figsize=(10,12))
plt.imshow(res)
plt.figure(figsize=(10,12))
plt.imshow(img_main)
导入cv2
将numpy作为np导入
方法=cv2.TM\u CCORR\u标准
阈值=0.7
img_main=cv2.imread('images/garden.jpg'))
模板=cv2.imread('images/frame\u trans.png',cv2.imread\u灰度)
模板\灰色=模板
img\u main\u gray=cv2.CVT颜色(img\u main,cv2.COLOR\u BGR2GRAY)
w、 h=模板。形状[:-1]
res=cv2.matchTemplate(img_main_gray,template_gray,method)
cv2.标准化(res,res,0.,1.,cv2.标准值_最小值)
cv2.阈值(分辨率,阈值,1,cv2.阈值至零)
i=0
border=45#我添加了这条线来控制必须为零的区域
而我<20:
最小值,最大值,最小位置,最大位置=cv2。最小最大位置(res)
打印(最大值)
如果[cv2.TM_SQDIFF,cv2.TM_SQDIFF_NORMED]中的方法:
左上=最小位置
其他:
左上=最大位置
如果最大值>阈值:
#打印(左上角)
右下=(左上[0]+w,左上[1]+h)
#cv2.圆圈(img_主,最大位置,5,(0,0255),1)
cv2.矩形(img_main,左上,右下,(0,0,255),5)
cv2.洪水填充(img_主灰色,无,左上角,0,0.1,1.0)
i+=1
res[max_loc[1]-边界:max_loc[1]+边界,max_loc[0]-边界:max_loc[0]+边界]=0#将max loc设置为零
img_main=cv2.cvt颜色(img_main,cv2.COLOR\u BGR2RGB)
将matplotlib.pyplot作为plt导入
plt.图(figsize=(10,12))
plt.imshow(res)
plt.图(figsize=(10,12))
plt.imshow(img_主)

以下是如何在Python/OpenCV中与透明模板图像进行模板匹配。很抱歉使用Imagemagick图像,但我已经有了这个示例

输入:

透明模板:


显示匹配位置边界框的结果:


以下是如何在Python/OpenCV中与透明模板图像进行模板匹配。很抱歉使用Imagemagick图像,但我已经有了这个示例

输入:

透明模板:


显示匹配位置边界框的结果:


@fmw42非常感谢您的想法!我把你的代码和我的代码划掉了,但我只得到一个结果(见下文)。 我的下一个问题:如何捕获少量结果

import cv2
import numpy as np

method = cv2.TM_CCORR_NORMED
threshold = 0.90

# read scene image
main_img = cv2.imread('images/garden.jpg')

# read template with alpha
template = cv2.imread('images/frame_trans.png', cv2.IMREAD_UNCHANGED)
h, w = template.shape[:2]

# extract template mask as grayscale from alpha channel and make 3 channels
tmplt_mask = template[:, :, 3]
tmplt_mask = cv2.merge([tmplt_mask, tmplt_mask, tmplt_mask])

# extract templt2 without alpha channel from tmplt
tmplt2 = template[:, :, 0:3]

res = cv2.matchTemplate(main_img, tmplt2, method, mask=tmplt_mask)

output_img = main_img.copy()

i = 0
while i < 100:
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
        top_left = min_loc
    else:
        top_left = max_loc

    if max_val > threshold:
        print("%s: %s" % (max_val, top_left))
        bottom_right = (top_left[0] + w, top_left[1] + h)
        cv2.rectangle(output_img, top_left, bottom_right, (0, 0, 255), 2)
        cv2.floodFill(res, None, top_left, 0, 0.1, 1.0)
    else:
        break
    i += 1

cv2.imwrite('sample8_output.png', output_img)
cv2.imshow('sample8', output_img)
cv2.waitKey()


结果图像输出
@fmw42非常感谢您的想法!我把你的代码和我的代码划掉了,但我只得到一个结果(见下文)。 我的下一个问题:如何捕获少量结果

import cv2
import numpy as np

method = cv2.TM_CCORR_NORMED
threshold = 0.90

# read scene image
main_img = cv2.imread('images/garden.jpg')

# read template with alpha
template = cv2.imread('images/frame_trans.png', cv2.IMREAD_UNCHANGED)
h, w = template.shape[:2]

# extract template mask as grayscale from alpha channel and make 3 channels
tmplt_mask = template[:, :, 3]
tmplt_mask = cv2.merge([tmplt_mask, tmplt_mask, tmplt_mask])

# extract templt2 without alpha channel from tmplt
tmplt2 = template[:, :, 0:3]

res = cv2.matchTemplate(main_img, tmplt2, method, mask=tmplt_mask)

output_img = main_img.copy()

i = 0
while i < 100:
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
        top_left = min_loc
    else:
        top_left = max_loc

    if max_val > threshold:
        print("%s: %s" % (max_val, top_left))
        bottom_right = (top_left[0] + w, top_left[1] + h)
        cv2.rectangle(output_img, top_left, bottom_right, (0, 0, 255), 2)
        cv2.floodFill(res, None, top_left, 0, 0.1, 1.0)
    else:
        break
    i += 1

cv2.imwrite('sample8_output.png', output_img)
cv2.imshow('sample8', output_img)
cv2.waitKey()


结果图像输出

我尝试在场景中使用泛光填充,就像在opencv示例中一样,但它不起作用。您正在尝试从
res
中找到最佳匹配,并且res是在
循环期间
之前计算的,因此在不更新
res
的情况下更改图像不会影响查找正确性,应用
泛洪填充后
不会发生任何情况。你让我在while循环中重新计算res,对吗?我有一个主意,在主图像上用黑色填充矩形,然后在循环中再次调用
matchTemplate
。不,这种方法可能会得到您想要的,但它很耗时,从计算角度来看,您不应该使用它,因为在
match template
import cv2
import numpy as np

method = cv2.TM_CCORR_NORMED
threshold = 0.90

# read scene image
main_img = cv2.imread('images/garden.jpg')

# read template with alpha
template = cv2.imread('images/frame_trans.png', cv2.IMREAD_UNCHANGED)
h, w = template.shape[:2]

# extract template mask as grayscale from alpha channel and make 3 channels
tmplt_mask = template[:, :, 3]
tmplt_mask = cv2.merge([tmplt_mask, tmplt_mask, tmplt_mask])

# extract templt2 without alpha channel from tmplt
tmplt2 = template[:, :, 0:3]

res = cv2.matchTemplate(main_img, tmplt2, method, mask=tmplt_mask)

output_img = main_img.copy()

i = 0
while i < 100:
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
        top_left = min_loc
    else:
        top_left = max_loc

    if max_val > threshold:
        print("%s: %s" % (max_val, top_left))
        bottom_right = (top_left[0] + w, top_left[1] + h)
        cv2.rectangle(output_img, top_left, bottom_right, (0, 0, 255), 2)
        cv2.floodFill(res, None, top_left, 0, 0.1, 1.0)
    else:
        break
    i += 1

cv2.imwrite('sample8_output.png', output_img)
cv2.imshow('sample8', output_img)
cv2.waitKey()


PyDev console: starting.
Python 3.8.2 (tags/v3.8.2:7b3ab59, Feb 25 2020, 23:03:10) [MSC v.1916 64 bit (AMD64)] on win32
runfile('D:/MyProjects/PyHeroRecognition/sample8_alpha.py', wdir='D:/MyProjects/PyHeroRecognition')
0.9918215870857239: (71, 45)
>>>