使用python查找视频中的图像

使用python查找视频中的图像,python,python-3.x,image-recognition,cv2,Python,Python 3.x,Image Recognition,Cv2,我想知道我的做法是否正确,或者是否有更有效的方法 我试图在视频中寻找图像,就像在视频的每一帧中,该图像可能包含在其中的某个位置(它不是全尺寸的帧,只是一个小帧) 当前正在将视频拉入图片,例如: import cv2 vidcap = cv2.VideoCapture('My_Video.mp4') success,image = vidcap.read() count = 0 success = True while success: success,image = vidcap.read(

我想知道我的做法是否正确,或者是否有更有效的方法

我试图在视频中寻找图像,就像在视频的每一帧中,该图像可能包含在其中的某个位置(它不是全尺寸的帧,只是一个小帧)

当前正在将视频拉入图片,例如:

import cv2
vidcap = cv2.VideoCapture('My_Video.mp4')
success,image = vidcap.read()
count = 0
success = True
while success:
  success,image = vidcap.read()
  print ('Read a new frame: ', success)
  cv2.imwrite("frame%d.jpg" % count, image)     # save frame as JPEG file
  count += 1
然后将其循环如下:

import cv2
import numpy as np
from matplotlib import pyplot as plt

img_rgb = cv2.imread('frame1.png')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('small_icon_I_am_looking_for.png',0)
w, h = template.shape[::-1]

res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where( res >= threshold)
for pt in zip(*loc[::-1]):
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)

cv2.imwrite('res.png',img_rgb)
有没有办法跳过图片的保存?我在数千小时的视频中这样做,我觉得保存和删除每一帧都会占用大量可能不需要的时间。你知道我如何在不需要每次保存图片的情况下搜索这个吗?这是一个例子,我的意思是,假设有一个超级马里奥的视频正在播放,它寻找这个硬币:

并将其检测为:


这目前是可行的,但只是在寻找更好的方法

如果我没有误解你的话,下面的内容应该有用。总的来说,您的代码编写得很好,只需要做您所要求的最小更改。由于while循环的结构,丢弃第一帧也存在问题。避免这种情况的一个好方法是循环半/while True构造:

import cv2
import numpy as np
from matplotlib import pyplot as plt

def process_img(img_rgb, template, count):
    img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)

    w, h = template.shape[::-1]

    res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
    threshold = 0.8
    loc = np.where( res >= threshold)
    for pt in zip(*loc[::-1]):
        cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)

    # This will write different res.png for each frame. Change this as you require
    cv2.imwrite('res{0}.png'.format(count),img_rgb)   


def main():
    vidcap = cv2.VideoCapture('My_Video.mp4')
    template = cv2.imread('small_icon_I_am_looking_for.png',0)  # open template only once
    count = 0
    while True:
      success,image = vidcap.read()
      if not success: break         # loop and a half construct is useful
      print ('Read a new frame: ', success)
      process_image(image, template, count)
      count += 1

你不能在阅读图像时对其进行处理吗?或者你的意思是避免在第二部分保存迷你帧?我的意思是在第一部分,就是不知道怎么做。你知道吗,我并没有太多地使用这种代码,这是我能做的最好的了。答案补充道,但我可能误解了你。请在评论中告诉我。这也将保存可能会占用计算机内存的每一帧。如果找到值,您可以添加一个条件以仅保存帧?取决于你想做什么。我还没有测试过,但这正是我想要的。希望它运行得更快。出色的工作:)@Lain似乎是一个很酷的节目!如果这不起作用或仍然很慢,请告诉我;我们可以尝试对其进行更多优化。我当然需要对其进行更多修改。理想情况下,它只需要检查每100帧(因为我在加载屏幕上检测到一个图标)。找到图标后,它也可以跳过20分钟的视频。我会尽力修改而不打扰你。有没有办法跳过主要框架的阅读?目前,它每100帧调用一次进程映像,但vidcap.read()只读取下一帧,我能告诉它像。。。例如,从现在开始100帧?对于我所需要的东西来说,速度仍然很慢。@Lain问题是一些视频编码使用当前帧的信息解码下一帧,因此很难对它们进行离散化。根据答案,显然可以使用
vidcap.grab()
跳过帧,但我对此不太确定。试试看!您是否有包含这些文件的github存储库?我可以试着看看代码在哪里运行得慢。