2012-03-23 33 views
2

我使用OpenCV和Python來處理視頻流。我想實現我自己的算法,所以我需要遍歷每個幀。使用OpenCV在Python中迭代CvMat的最快方式是什麼?

我到目前爲止的工作,但方式太慢,不能實時。我知道Python不是最高效的編程語言,但我認爲它可以做得比這更好,因爲內置的圖像轉換功能非常快。 Numpy可能是要走的路,但我還不熟悉它。

import cv, numpy 
vidFile = cv.CaptureFromFile('sample.avi') 
nFrames = int( cv.GetCaptureProperty(vidFile, cv.CV_CAP_PROP_FRAME_COUNT)) 
for f in xrange(nFrames): 
    frameImg = cv.QueryFrame(vidFile) 
    frameMat=cv.GetMat(frameImg) 
    print "mat ", mat[3,1] 
    for x in xrange(frameMat.cols): 
    for y in xrange(frameMat.rows): 
     # just an example, multiply all 3 components by 0.5 
     frameMat[y, x] = tuple(c*0.5 for c in frameMat[y, x]) 
    cv.ShowImage("My Video Window", frameMat) 
    if cv.WaitKey(waitPerFrameInMillisec ) == 27: 
    break 

我該如何加快這個過程? 謝謝,b_m

回答

3

OpenCV有很不錯的python文檔here。基本上你應該總是嘗試使用這些內置的opencv函數或numpy來對視頻幀進行操作。對於幀處理看一看operations on arrays,用這個你可以通過像素處理循環,這是荒謬的慢替換整個像素:

frameMat=cv.GetMat(frameImg) 
print "mat ", mat[3,1] 
for x in xrange(frameMat.cols): 
    for y in xrange(frameMat.rows): 
     # just an example, multiply all 3 components by 0.5 
     frameMat[y, x] = tuple(c*0.5 for c in frameMat[y, x]) 
cv.ShowImage("My Video Window", frameMat) 

有:

cv.ConvertScale(frameImg, frameImg, scale=0.5) 
cv.ShowImage("My Video Window", frameImg) 

,輕鬆地進行實時播放,有很多很酷的功能可以讓你合併視頻等。

+0

我知道這是正確的方式,我已經這樣做了,但現在我需要做一些操作,如果不循環數組,就無法執行操作。那麼,這可能是可能的,但我不知道如何。例如,如何找到圖像的第一個(左上角)紅色像素?這些東西將會是循環的小菜一碟。 – 2012-03-23 19:10:26

+1

@b_m - 'frameImg [0,0]'會爲您提供左上角像素的RGB值。你能解釋你真正想做什麼嗎?然後可能能夠幫助更多;) – fraxel 2012-03-23 19:25:06

+0

我的意思是第一個像素是紅色的。我甚至不知道我想從長遠來看做什麼,我只是看到,在某些時候使用循環是不可避免的。 – 2012-03-23 19:32:04

1

Python for循環太慢了。如果您可以使用內置函數(或numpy或其他擴展模塊)來表達您的算法,請執行此操作。例如,乘以常數的示例很容易用ConvertScale實現。如果算法更復雜,則必須在C級實現它。 Cython是一種讓人更容易的流行方式。

+0

這可能是一個好主意,我會研究它。有一個名爲opencv-cython的項目,但它使用了opencv2.0。 – 2012-03-26 20:57:13

相關問題