OpenCV和; Visual C ++:从Camera保存帧数据,然后保存到Jpg

时间:2011-02-08 21:09:55

标签: c++ opencv virtual webcam

我是 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;
}

3 个答案:

答案 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文件而不是网络摄像头检索帧,但是将帧保存到磁盘的方法是一样的!