2016-12-26 13 views
1

Мне было интересно, если я пойду по этому правильному пути или если есть способ, который намного эффективнее.Найти изображение внутри видео с помощью 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) 

Есть ли способ, возможно, пропустить сохранение снимков? Я делаю это через тысячи часов видео, и сохранение и удаление каждого кадра, который я чувствую, будет использовать тонну времени, которое может не понадобиться. Любые идеи, как я могу искать это без необходимости сохранять изображение каждый раз? Это пример того, что я имею в виду, скажем, там было видео супер Марио играется, он ищет монеты:

Coin

и определяет ее как таковую:

Coin detected

В настоящее время это работает, но просто ищет лучший способ.

+0

Не могли бы вы обрабатывать изображения по мере их чтения? Или вы хотите избежать экономии мини-кадров во второй части? – gowrath

+0

Я имею в виду в первой части, просто не мог понять, как это сделать. Вы знаете, как я много работал с таким кодом, и это было лучшее, что я мог сделать. – Lain

+0

Ответ добавлен, но я, возможно, вас неправильно понял. Дай мне знать в комментариях. – gowrath

ответ

1

Если я не понял вас неправильно, нижеследующее должно работать. В целом ваш код хорошо написан с минимальными изменениями, необходимыми для выполнения того, что вы просите. Также возникла проблема с отказом первого кадра из-за структуры вашего цикла 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 
+0

Еще не проверены, но это выглядит именно так, что я искал. Надеюсь, это работает намного быстрее. Фантастическая работа :) – Lain

+0

@Lain Кажется, классная программа! Сообщите мне, если это не работает или все еще медленное; мы можем попытаться оптимизировать его больше. – gowrath

+0

Мне, безусловно, нужно его модифицировать. В идеале нужно только проверять каждый 100-й кадр (поскольку я обнаруживаю значок на экране загрузки). После того, как он найдет значок, он может пропустить и 20 минут видео. Я делаю все возможное, чтобы изменить, не беспокоя вас. – Lain