Cpp--opencv中连续储存多帧图片技巧

来源:互联网 发布:知豆新能源汽车价格表 编辑:程序博客网 时间:2024/06/13 09:58

做过opencv方面的人都知道,在项目中经常需要自动要输出几帧图片,但是好像每次都要手动去改储存图片的名字,如果不这样,虽然程序执行了,但是因为名字相同,还是会覆盖前面的几帧。

cvSaveImage函数中的图片名字是个字符串,不可能在程序中每次自动更改,那我们用什么方法呢?我们需要在这个字符串上做手脚。大家知道,C++中并没有字符串类型,我们用的,都可以认为是字符数组。那么这个地址值其实也就是一个指向特殊字符串地址的指针。

于是,用分解的方法就可以实现这个目的。例如地址为“E:/test/i.jpg”。我们不可以直接改变i的值,那么我们就可以分为:“E:/test/“,i,”.jpg“三个字符串。可能就有人要问了:i不是for循环中定义的整形数么?(for(int i=0;i<10;i++))。对,确实是这样,但是在头文件<stdlib.h>下,我们有一些可以进行数据类型转换的函数。我们这里用到了itoa函数。

先看看定义:char   *itoa(int   value,char   *string,int   radix) 将整数value转换成字串存入string,radix为转换所用基数.。最终我们得到的还是一个指向字符串的指针,那么就ok了。

接下来我们直接看看代码和实现:

#include "camera.h"#include <highgui.h>#include <stdio.h>#include<iostream>#include "string.h"#include<stdlib.h>using namespace std;using namespace cv;int main(){int cam_count;//仅仅获取摄像头数目cam_count = CCamera::CameraCount();printf("There are %d cameras.\n", cam_count);//获取所有摄像头的名称for(int i=1; i <= cam_count; i++){char camera_name[1024];  CCamera::CameraName(i, camera_name, sizeof(camera_name) );printf("Camera #%d's Name is '%s'.\n", i, camera_name);}if(cam_count==0)return -1;CCamera camera1;CCamera camera2;//打开第一个摄像头,检查第二个摄像头if(! camera1.OpenCamera(1, 10000,10000)) //用代码制定图像宽和高{fprintf(stderr, "Can not open camera1.\n");return -1;}cvNamedWindow("camera1");//Sleep(100);if (cam_count>1){if(! camera2.OpenCamera(1)) //if(! camera2.OpenCamera(1, 2048,1536)) //用代码制定图像宽和高{fprintf(stderr, "Can not open camera2.\n");return -1;}cvNamedWindow("camera2");}IplImage *pFrame1 = 0;IplImage *pFrame2 = 0;if (cam_count==1)//连续采集{while(1){//获取帧for(int i=0;i<10;i++){pFrame1 = camera1.QueryFrame();//显示//char *arr1 = new char[];   char arr1[] = "E:/test/";   char *arr2 = new char[];   itoa(i,arr2,10);       char arr3[] = ".jpg";   strcat(arr1,arr2);   strcat(arr1,arr3);   cout<<arr1<<endl;   cout<<"true"<<endl;    //cvShowImage("camera1", pFrame1);cvSaveImage(arr1, pFrame1 );   }   break;if (cvWaitKey(20) == 'q')//不懂,这是检测什么?   break;}}else{while(1){//获取一帧pFrame1 = camera1.QueryFrame();//显示cvShowImage("camera1", pFrame1);pFrame2 = camera2.QueryFrame();cout<<"false"<<endl;//显示cvShowImage("camera2", pFrame2);if (cvWaitKey(20) == 'q')break;}}camera1.CloseCamera(); //可不调用此函数,CCamera析构时会自动关闭摄像头cvDestroyWindow("camera1");if (cam_count>1){camera2.CloseCamera(); //可不调用此函数,CCamera析构时会自动关闭摄像头cvDestroyWindow("camera2");}return 0;}
if (cam_count==1)//连续采集{while(1){//获取帧for(int i=0;i<10;i++){pFrame1 = camera1.QueryFrame();//显示//char *arr1 = new char[];   char arr1[] = "E:/test/";   char *arr2 = new char[];   itoa(i,arr2,10);       char arr3[] = ".jpg";   strcat(arr1,arr2);   strcat(arr1,arr3);   cout<<arr1<<endl;   cout<<"true"<<endl;    //cvShowImage("camera1", pFrame1);cvSaveImage(arr1, pFrame1 );   }   break;if (cvWaitKey(20) == 'q')//不懂,这是检测什么?   break;}}
注意在cvSaveImage中arr1本身就是个字符串数组,不需要再加引号。这样,就完美的实现了用不同的名称储存多帧图像。



但是还是存在一些问题就是arr1的内存会崩溃,不知道是不是因为在后面多次使用字符串连接函数。待解决。




我们再附上常用的数据类型转换函数:

char   *ultoa(unsigned   long   value,char   *string,int   radix)   
将无符号整型数value转换成字符串并返回该字符串,radix为转换时所用基数   
char   *ltoa(long   value,char   *string,int   radix)   
将长整型数value转换成字符串并返回该字符串,radix为转换时所用基数   
char   *itoa(int   value,char   *string,int   radix) 
将整数value转换成字串存入string,radix为转换所用基数.   
double atof(char   *nptr)                   
将字符串nptr转换成双精度数,并返回这个数,错误返回0   
int     atoi(char   *nptr)                               
将字符串nptr转换成整型数,     并返回这个数,错误返回0   
long     atol(char   *nptr)     
将字符串nptr转换成长整型数,并返回这个数,错误返回0   
double strtod(char   *str,char   **endptr)   
将字符串str转换成双精度数,并返回这个数,   
long strtol(char   *str,char   **endptr,int   base)   
将字符串str转换成长整型数,   并返回这个数,


我们来看另一种形式的实现:

#include<iostream>#include<sstream>#include<string>using namespace std;double sciToDub(const string&str){stringstream ss(str);double d=0;ss>>d;if(ss.fail()){string s="unable to format";s+=str;s+="as a number!";throw(s);}return (d);}int main(){try{cout<<sciToDub("1.234e5")<<endl;cout<<sciToDub("6.02e-2")<<endl;cout<<sciToDub("asdf")<<endl;}catch(string &e){cerr<<"whoops:"<<e<<endl;}}


0 0
原创粉丝点击