回答
這樣做的唯一可行的方法是手動提取幀,緩衝它們(在內存或文件上),然後以相反的順序重新加載它們。
問題是視頻壓縮器都在利用時間冗餘 - 兩個連續幀大部分時間非常相似的事實。所以,他們不時編碼一個全幀(通常每幾百幀),然後只發送前一個和當前的差異。
現在,爲了解碼工作,它必須以相同的順序完成 - 解碼一個關鍵幀(一個完整的),然後爲每個新幀添加差異來獲取當前圖像。
該策略使得在視頻中反轉播放變得非常困難。有幾種技術,但都涉及緩衝。
現在,您可能已經看到了由Astor描述的CV_CAP_PROP_POS_FRAMES參數。看起來沒問題,但由於上述問題,OpenCV無法正確跳轉到特定幀(在這些問題上存在多個錯誤)。他們(OpenCV開發者)正在研究一些解決方案,但即使這些解決方案也會非常緩慢(它們涉及回到上一個關鍵幀,然後解碼回選定的一個)。如果使用這種技術,每幀平均必須被解碼數百次,使其非常緩慢。然而,它不起作用。
編輯 如果您追求緩衝方式來逆轉它,請記住,解碼後的視頻會快速消耗常規計算機的內存資源。一個普通的720p視頻一分鐘長需要4.7GB解壓縮的內存!將幀作爲單個文件存儲在磁盤上是解決此問題的實際解決方案。
是的,這是可能的。請參閱評論代碼:
//create videocapture
VideoCapture cap("video.avi");
//seek to the end of file
cap.set(CV_CAP_PROP_POS_AVI_RATIO, 1);
//count frames
int number_of_frames = cap.get(CV_CAP_PROP_POS_FRAMES);
//create Mat frame and window to display
Mat frame;
namedWindow("window");
//main loop
while (number_of_frames > 0)
{
//decrease frames and move to needed frame in file
number_of_frames--;
cap.set(CV_CAP_PROP_POS_FRAMES, number_of_frames);
//grab frame and display it
cap >> frame;
imshow("window", frame);
//wait for displaying
if (waitKey(30) >= 0)
{
break;
}
}
也讀this文章。
cap.set(CV_CAP_PROP_POS_FRAMES,number_of_frames);確實會影響CPU,但工作。 –
另一種解決方案,類似於ArtemStorozhuk's answer是使用FPS從幀域移動到時域,然後尋求向後使用CV_CAP_PROP_POS_MSEC
(其不錘擊CPU等CV_CAP_PROP_POS_FRAMES
可以)。這裏是我的示例代碼,它完全適用於.mpg,只使用大約50%的CPU。
#include <opencv2/opencv.hpp>
int main (int argc, char* argv[])
{
cv::VideoCapture cap(argv[1]);
double frame_rate = cap.get(CV_CAP_PROP_FPS);
// Calculate number of msec per frame.
// (msec/sec/frames/sec = msec/frame)
double frame_msec = 1000/frame_rate;
// Seek to the end of the video.
cap.set(CV_CAP_PROP_POS_AVI_RATIO, 1);
// Get video length (because we're at the end).
double video_time = cap.get(CV_CAP_PROP_POS_MSEC);
cv::Mat frame;
cv::namedWindow("window");
while (video_time > 0)
{
// Decrease video time by number of msec in one frame
// and seek to the new time.
video_time -= frame_msec;
cap.set(CV_CAP_PROP_POS_MSEC, video_time);
// Grab the frame and display it.
cap >> frame;
cv::imshow("window", frame);
// Necessary for opencv's event loop to work.
// Wait for the length of one frame before
// continuing the loop. Exit if the user presses
// any key. If you want the video to play faster
// or slower, adjust the parameter accordingly.
if (cv::waitKey(frame_msec) >= 0)
break;
}
}
所以..尋求msec是不是CPU消耗,逐幀尋找?爲什麼?因爲壓縮? – nkint
我認爲這與視頻編碼的方式有關......每個數據包中都有一個時間戳,指示自視頻開始以來的時間,所以在視頻中尋找特定時間是一種簡單的二進制搜索操作。但我並不是視頻編碼方面的專家,所以請在評論中加上一點鹽分。 –
- 1. iOS中的反向視頻播放
- 2. 使用opencv播放視頻
- 3. Opencv播放視頻太慢
- 4. 在視頻播放中播放視頻
- 5. 使用HTML5視頻元素反向播放視頻
- 6. 如何在HTML中反向播放視頻
- 7. 播放視頻向後
- 8. 簡單的視頻播放OpenCV,C++
- 9. 如何使用opencv播放視頻?
- 10. OpenCV同時播放2個視頻
- 11. Opencv樹莓pi 3視頻播放C++
- 12. 設備音頻播放時視頻不播放,反之亦然
- 13. 視頻播放器播放視頻
- 14. 在Flash播放器中播放視頻
- 15. 使用AVPlayer和Swift在IOS上反向播放視頻9
- 16. 在iphone中播放視頻播放器中的視頻播放器
- 17. 在視頻中播放視頻c
- 18. 在視頻播放器中播放youtube視頻
- 19. 在Brightcove視頻播放器中播放第三方視頻
- 20. 如何在視頻播放器中播放視頻
- 21. 如何在YouTube視頻播放器中播放YouTube視頻中的視頻android
- 22. 在iOS上向後播放HTML5視頻
- 23. MediaPlayer MPMoviePlayerController - 不在橫向播放視頻
- 24. 在橫向(iPhone)全屏播放視頻
- 25. 以橫向方向播放Android視頻
- 26. 在UITableViewCell中播放視頻
- 27. 在CardView中播放視頻
- 28. 在AVPlayer中播放視頻
- 29. 在OSX中播放視頻
- 30. 在Extjs中播放視頻
好的答案+1。不知道。你是否爲OpenCV編碼? – ArtemStorozhuk
:)不是yey,雖然我正在考慮一些補丁。但是我在VideoCapture syncronization方面遇到了一些問題,並且發現了一些缺陷。 – Sam
好吧,謝謝你的幫助 – darasan