OpenCV 与Virtual C++:保存来自Camera的帧数据,然后保存为Jpg

发布于 2024-10-16 18:58:40 字数 1217 浏览 4 评论 0原文

我是 OpenCVC++ 初学者。我的学生项目遇到问题。我的导师想要从相机中抓取帧并将抓取的帧保存为 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;
}

I am an OpenCV and C++ beginner. I've got a problem with my student project.My Tutor wants to grab frames from a Camera and save the grabbed frames into jpg. So first I used "cvCreateCameraCapture,cvQueryFrame,cvSaveImage" and it worded ok. But the frame is relative big,about 2500x2000,and it takes about 1 second to save one Frame. But my Tutor requires at least to save 10 Frames per second.

Then I came out the ideas to save raw data first and after grabbing process I can save them into Jpg. So I wrote following test code.But the problem is that all the saved Images are the same and it seems they are just from the data of the last grabbed frame.I guess the problem is about my poor knowledge of c++ especially pointers.So I really hope to get help here.

Thanks in advance!

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

彼岸花ソ最美的依靠 2024-10-23 18:58:40

如果你使用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;
}

If you use C++, why don't you use the C++ opencv interface?
The reason you get N times the same image is that the capture reuses the memory for each frame, if you want to store the frames you need to copy them. Example for the C++ interface:

#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;
}
月下伊人醉 2024-10-23 18:58:40

您有多核/多 CPU 系统吗?然后,您可以将 1 秒的任务分配给 16 个核心,并节省 16 帧/秒!

或者您可以在 Cuda/OpenCL 的 GPU 上编写自己的优化 jpeg 例程。

如果您需要它运行更长时间,您可以将原始图像数据转储到磁盘,然后稍后将其读回并转换为 jpeg。 5Mpixel * 3color * 10fps 是 150Mb/s(感谢 etarion!),您可以使用两个磁盘和 Windows Raid 来实现。

编辑:如果您只需要执行 10 帧,那么只需将它们缓冲在内存中,然后按照其他答案所示将它们写出来。

Do you have a multicore/multiple CPU system? Then you could farm out the 1second tasks across 16cores and save 16frames/second !

Or you could write your own optimized jpeg routine on the GPU in Cuda/OpenCL.

If you need it to run for longer you could dump the raw image data to disk, then read it back in later and convert to jpeg. 5Mpixel * 3color * 10fps is 150Mb/s (thanks etarion!) which you can do with two disks and windows Raid.

edit: If you only need to do 10frames then just buffer them in memory and then write them out as the other answer shows.

自此以后,行同陌路 2024-10-23 18:58:40

由于您已经知道如何检索帧,请检查以下答案:

openCV:如何将视频分割成图像序列?

这个问题有点不同,因为它从 AVI 文件而不是网络摄像头检索帧,但将帧保存到磁盘的方法是相同的!

Since you already know how to retrieve a frame, check this answer:

openCV: How to split a video into image sequence?

This question is a little different because it retrieves frames from an AVI file instead of a webcam, but the way to save a frame to the disk is the same!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文