使用 python 在视频中查找图像
Find an image inside of a video using python
我想知道我这样做是否正确,或者是否有更有效的方法。
我正在尝试在视频中寻找图像,就像在视频的每一帧上,该图像可能包含在其中某处(它不是全尺寸帧,只是一个小帧)。
目前正在将视频拉成这样的图片:
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 循环的结构,您丢弃第一帧也存在问题。避免这种情况的一个好方法是循环和 half/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
我想知道我这样做是否正确,或者是否有更有效的方法。
我正在尝试在视频中寻找图像,就像在视频的每一帧上,该图像可能包含在其中某处(它不是全尺寸帧,只是一个小帧)。
目前正在将视频拉成这样的图片:
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 循环的结构,您丢弃第一帧也存在问题。避免这种情况的一个好方法是循环和 half/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