問題描述:關鍵幀提取后,將會得一序列關鍵幀的幀號,然后需要把這些幀保存起來,以便於瀏覽和管理.
通過opencv里的VideoCapture的函數set(CV_CAP_PROP_POS_FRAMES,nextFrameNumber),定位到具體的幀號,但最終讀取的並不是對應幀的圖像.
問題出現的原因:
Opencv底層是通過ffmpeg讀取視頻.其中定位主要用av_seek_frame()來定位frame的位置.
int av_seek_frame(AVFormatContext *s,int stream_index,int64_t timestamp,int flags)其中最后一個參數有
AVSEEK_FLAG_BACKWARD = 1 // seek backward
AVSEEK_FLAG_BYTE = 2 // seeking based on position in bytes
AVSEEK_FLAG_ANY = 4 // seek to any frame,even non key-frames.
ffmpeg默認的是選取關鍵幀,opencv里面這個函數的參數flag是0.
因而,進行定位時,若下一幀不是關鍵幀,進行讀取時會出跳躍現象.
將參數改為AVSEEK_FLAG_ANY,雖然可以解決跳躍現象,讀取任何幀圖像.
但是將會出現花屏現象,因為幀圖像解碼是需要利用關鍵幀的圖像進行幀間的解碼,
若讀取幀圖像時,其對應關鍵幀沒有被讀取解碼,將只會對該幀進行幀內解碼得到花屏圖像.
如何才能解決跳躍現象,但不產生花屏圖像?
解決思路:讀取下一幀號最相近且前面的關鍵幀,然后一幀幀的讀取視頻,直到讀到下一幀的幀號為止.
將Opencv2.3.1里面的cap_ffmpeg_impl.cpp里面bool CvCapture_FFMPEG::setProperty( int property_id, double value )函數改成如下實現方式,
即可達到准確定位的效果.

