OpenCV 与Virtual C++:保存来自Camera的帧数据,然后保存为Jpg
我是 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;
}
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果你使用C++,为什么不使用C++ opencv接口呢?
你得到 N 次相同图像的原因是捕获重用了每一帧的内存,如果你想存储帧你需要复制它们。 C++ 接口示例:
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:
您有多核/多 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.
由于您已经知道如何检索帧,请检查以下答案:
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!