我是 OpenCV 和 C ++ 初学者。我的学生项目有问题。我的导师希望从相机中抓取帧并将抓取的帧保存到jpg中。所以首先我使用了"cvCreateCameraCapture,cvQueryFrame,cvSaveImage"
并且说得好。但框架相对较大,大约2500x2000,保存一帧需要大约1秒。但我的导师要求每秒至少节省10帧。
然后我首先提出了保存原始数据的想法,在抓取过程之后我可以将它们保存到Jpg中。所以我写了下面的测试代码。但问题是所有保存的图像是相同的,似乎它们只是来自最后一个抓取帧的数据。我猜问题是关于我对c ++的不了解,特别是指针。所以我真的希望在这里得到帮助。
提前致谢!
void COpenCVDuoArryTestDlg::OnBnClickedButton1()
{
IplImage* m_Frame=NULL;
TRACE("m_Frame initialed");
CvCapture * m_Video=NULL;
m_Video=cvCreateCameraCapture(0);
IplImage**Temp_Frame= (IplImage**)new IplImage*[100];
for(int j=0;j<100;j++){
Temp_Frame[j]= new IplImage [112];
}
TRACE("Tempt_Frame initialed\n");
cvNamedWindow("video",1);
int t=0;
while(m_Frame=cvQueryFrame(m_Video)){
for(int k=0;k<m_Frame->nSize;k++){
Temp_Frame[t][k]= m_Frame[k];
}
cvWaitKey(30);
t++;
if(t==100){
break;
}
}
for(int i=0;i<30;i++){
CString ImagesName;
ImagesName.Format(_T("Image%.3d.jpg"),i);
if(cvWaitKey(20)==27) {
break;
}
else{
cvSaveImage(ImagesName, Temp_Frame[i]);
}
}
cvReleaseCapture(&m_Video);
cvDestroyWindow("video");
TRACE("cvDestroy works\n");
delete []Temp_Frame;
}
答案 0 :(得分:1)
如果使用C ++,为什么不使用C ++ opencv接口? 如果要存储需要复制它们的帧,则获得N次相同图像的原因是捕获会重用每帧的内存。 C ++接口的示例:
#include <vector>
#include "cv.h"
#include "highgui.h"
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("image",1);
std::vector<cv::Mat> images(100);
for(int i = 0; i < 100;++i) {
// this is optional, preallocation so there's no allocation
// during capture
images[i].create(480, 640, CV_8UC3);
}
for(int i = 0; i < 100;++i)
{
Mat frame;
cap >> frame; // get a new frame from camera
frame.copyTo(images[i]);
}
cap.release();
for(int i = 0; i < 100;++i)
{
imshow("image", images[i]);
if(waitKey(30) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
答案 1 :(得分:0)
您有多核/多CPU系统吗?然后你可以在16个核心中分配1秒的任务并节省16帧/秒!
或者您可以在Cuda / OpenCL中的GPU上编写自己的优化jpeg例程。
如果你需要它运行更长时间,你可以将原始图像数据转储到磁盘,然后再读回来并转换为jpeg。 5Mpixel * 3color * 10fps是150Mb / s(感谢etarion!),你可以使用两个磁盘和窗口Raid。
编辑:如果你只需要做10帧,那么只需将它们缓冲在内存中,然后将其写出来,如另一个答案所示。
答案 2 :(得分:0)
由于您已经知道如何检索框架,请检查以下答案:
openCV: How to split a video into image sequence?
这个问题有点不同,因为它从AVI文件而不是网络摄像头检索帧,但是将帧保存到磁盘的方法是一样的!