2016-12-26 10 views
1

私はこれについて正しい方向に進むのか、もっと効率的な方法があるのか​​疑問に思っていました。Pythonを使用してビデオ内の画像を検索

ビデオの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) 

は、おそらく画像の保存をスキップする方法はありますか?私は何千時間ものビデオを通してこれをやっており、必要ではないかもしれない時間を使って感じるフレームをすべて保存して削除しています。毎回画像を保存する必要なしに、これをどのように検索することができますか?これは、私が何を意味するかの一例である再生されているスーパーマリオの映像があったと言う、それがこのコインを探します:

Coin

、そのようにそれを検出します。

Coin detected

これは現在機能していますが、より良い方法を探しています。

+0

あなたがそれらを読むときにイメージを処理できませんか?または、2番目の部分にミニフレームを保存しないでください。 – gowrath

+0

最初の部分では、どうやってそれを行うのか分かりませんでした。どういうわけか、私はこの種のコードではあまり働かなかったし、これが私ができる最高のものだった。 – Lain

+0

回答が追加されましたが、私はあなたを誤解している可能性があります。コメントで私に教えてください。 – gowrath

答えて

1

私があなたに誤解していない場合は、以下が有効です。全体として、あなたのコードはあなたが求めていることをするのに必要な最小限の変更だけで書かれています。あなたのwhileループの構造のため、最初のフレームを破棄する問題もありました。これを避けるための良い方法は、ループと半分/真のコンストラクトです:

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

関連する問題