我是OpenCV的初学者。我想对正在上传到我的服务器的视频帧进行一些图像处理。我只是想读取可用的帧并将它们写在目录中。等待视频的其他部分上传并将帧写入目录。我应该等待每个帧完全上传然后将其写入文件。
你能告诉我怎样才能用OpenCV(Python)做到这一点?
编辑1:
我编写了此代码用于从文件中捕获视频,而新数据则附加在文件末尾。换句话说,out.mp4
文件不是完整的视频,而另一个程序正在其上写入新的帧。我要做的是,等待其他程序写入新帧然后读取它们并显示它们。
这是我的代码:
import cv2
cap = cv2.VideoCapture("./out.mp4")
while True:
if cap.grab():
flag, frame = cap.retrieve()
if not flag:
continue
else:
cv2.imshow('video', frame)
if cv2.waitKey(10) == 27:
break
所以问题是cap.grab()
电话!当没有框架时,它将返回False
!即使我等了很长时间,它也不再捕捉帧了。
答案 0 :(得分:44)
阅读VideoCapture
的文档后。我发现您可以告诉VideoCapture
,我们在下次调用VideoCapture.read()
(或VideoCapture.grab()
)时要处理哪个框架。
问题是当你想要read()
未准备好的帧时,VideoCapture
对象会卡在该帧上并且永远不会继续。所以你必须强制它从前一帧开始。
这是代码
import cv2
cap = cv2.VideoCapture("./out.mp4")
while not cap.isOpened():
cap = cv2.VideoCapture("./out.mp4")
cv2.waitKey(1000)
print "Wait for the header"
pos_frame = cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES)
while True:
flag, frame = cap.read()
if flag:
# The frame is ready and already captured
cv2.imshow('video', frame)
pos_frame = cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES)
print str(pos_frame)+" frames"
else:
# The next frame is not ready, so we try to read it again
cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, pos_frame-1)
print "frame is not ready"
# It is better to wait for a while for the next frame to be ready
cv2.waitKey(1000)
if cv2.waitKey(10) == 27:
break
if cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES) == cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT):
# If the number of captured frames is equal to the total number of frames,
# we stop
break
答案 1 :(得分:12)
使用此 -
import cv2
cap = cv2.VideoCapture('path of video file')
count = 0
while cap.isOpened():
ret,frame = cap.read()
cv2.imshow('window-name',frame)
cv2.imwrite("frame%d.jpg" % count, frame)
count = count + 1
if cv2.waitKey(10) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows() # destroy all the opened windows
答案 2 :(得分:8)
根据OpenCV 3.0及更高版本的最新更新,您需要在Mehran的代码中更改属性标识符,如下所示:
cv2.cv.CV_CAP_PROP_POS_FRAMES
到
cv2.CAP_PROP_POS_FRAMES
同样适用于cv2.CAP_PROP_POS_FRAME_COUNT
。
希望它有所帮助。
答案 3 :(得分:7)
在openCV的文档中,有一个example用于逐帧获取视频。它是用c ++编写的,但是将示例移植到python非常容易 - 你可以搜索每个fumction文档,看看如何在python中调用它们。
#include "opencv2/opencv.hpp"
using namespace cv;
int main(int, char**)
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
Mat edges;
namedWindow("edges",1);
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
cvtColor(frame, edges, CV_BGR2GRAY);
GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
Canny(edges, edges, 0, 30, 3);
imshow("edges", edges);
if(waitKey(30) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
答案 4 :(得分:2)
这就是我开始解决这个问题的方法:
创建视频编写器:
import cv2.cv as cv
videowriter = cv.CreateVideoWriter( filename, fourcc, fps, frameSize)
循环检索[1]并写入帧:
cv.WriteFrame( videowriter, frame )
[1] zenpoy已经指出了正确的方向。您只需要知道可以从网络摄像头或文件中检索图像: - )
希望我理解这些要求是正确的。
答案 5 :(得分:2)
我找到的唯一解决方案是不将索引设置为前一帧并等待(然后OpenCV停止读取帧,无论如何),但是再次初始化捕获。所以,它看起来像这样:
cap = cv2.VideoCapture(camera_url)
while True:
ret, frame = cap.read()
if not ret:
cap = cv.VideoCapture(camera_url)
continue
# do your processing here
它完美无缺!
答案 6 :(得分:0)
这是一个例子,其中 a.mp4 是视频文件
import cv2
cap = cv2.VideoCapture('a.mp4')
count = 0
while cap.isOpened():
ret,frame = cap.read()
if not ret:
continue
cv2.imshow('window-name', frame)
#cv2.imwrite("frame%d.jpg" % count, frame)
count = count + 1
if cv2.waitKey(10) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()