楼主最近在做一个人脸识别的项目,刚好有个一个树莓派3B,于是准备拿来做终端使用,使用命令行和python拍照都很简单,但是速度感人,就想使用opencv拍照,结果网上很多方法都有问题,只能使用USB的摄像头,最终用了gayhub上的一个开源项目raspicam成功调用了opencv
地址:https://github.com/cedricve/raspicam
raspicam提供了2种方式拍照,有一种是直接使用C++的,还有一种使用opencv的,opencv安装方法网上很多,和linux一样需要自己编译,等上2小时左右就行了,然后去raspicam的地址下载源码解压,cd进入文件夹,然后:
mkdir build
cd build
cmake ..
等一会儿就完成了
接下来测试一下,我用的开发环境是QT(推荐使用apt-fast下载,不然等半天,安装教程:http://blog.csdn.net/coekjin/article/details/52049273),新建一个项目,打开pro文件加入以下内容:
INCLUDEPATH += /usr/local/include \ /usr/local/include/opencv \ /usr/local/include/opencv2 \ /usr/local/include/raspicam LIBS += /usr/local/lib/libopencv_highgui.so \ /usr/local/lib/libopencv_core.so \ /usr/local/lib/libopencv_imgproc.so \ /usr/local/lib/libopencv_video.so \ /usr/local/lib/libopencv_videoio.so \ /usr/local/lib/libopencv_videostab.so \ /usr/local/lib/libraspicam.so \ /usr/local/lib/libraspicam_cv.so \ -L/usr/local/lib \ -lopencv_core \ -lopencv_imgcodecs \ -lopencv_highgui \ -lopencv_video \ -lopencv_videoio \ -lopencv_videostab \ -lraspicam \ -lraspicam_cv
然后复制gayhub上的第一段代码,修改成子函数调用:
#include <ctime> #include <fstream> #include <iostream> #include <raspicam/raspicam.h> using namespace std; int shoot() { raspicam::RaspiCam Camera; //Camera object //Open camera cout<<"Opening Camera..."<<endl; if ( !Camera.open()) {cerr<<"Error opening camera"<<endl;return -1;} //wait a while until camera stabilizes cout<<"Sleeping for 3 secs"<<endl; sleep(3); //capture Camera.grab(); //allocate memory unsigned char *data=new unsigned char[ Camera.getImageTypeSize ( raspicam::RASPICAM_FORMAT_RGB )]; //extract the image in rgb format Camera.retrieve ( data,raspicam::RASPICAM_FORMAT_RGB );//执行完这句data就是bmp24的原始数据,可以给它加上文件头保存为bmp //save std::ofstream outFile ( "raspicam_image.ppm",std::ios::binary ); outFile<<"P6\n"<<Camera.getWidth() <<" "<<Camera.getHeight() <<" 255\n"; outFile.write ( ( char* ) data, Camera.getImageTypeSize ( raspicam::RASPICAM_FORMAT_RGB ) ); outFile.close()//建议加上 cout<<"Image saved at raspicam_image.ppm"<<endl; //free resrources delete[] data;//原代码是delete data,建议修改成和我一样的 return 0; }
修改代码中的文件位置,编译运行,就可以看到保存结果,ppm格式的,打不开的话可以拖到你的播放器里面试试
如果要转成BMP格式,给它加上58位的文件头就行了,代码在:http://blog.csdn.net/libin88211/article/details/36186535
当然如果只是这样是不需要opencv的,而且bmp格式的文件太大,所以可以直接使用gayhub下面的代码直接保存bmp或者jpg,代码里面改下文件名就行了:
#include <ctime> #include <iostream> #include <raspicam/raspicam_cv.h> using namespace std; int shootopencv () { time_t timer_begin,timer_end; raspicam::RaspiCam_Cv Camera; cv::Mat image; int nCount=100; //set camera params Camera.set( CV_CAP_PROP_FORMAT, CV_8UC1 ); //Open camera cout<<"Opening Camera..."<<endl; if (!Camera.open()) {cerr<<"Error opening the camera"<<endl;return -1;} //Start capture cout<<"Capturing "<<nCount<<" frames ...."<<endl; time ( &timer_begin ); for ( int i=0; i<nCount; i++ ) { Camera.grab(); Camera.retrieve ( image); if ( i%5==0 ) cout<<"\r captured "<<i<<" images"<<std::flush; } cout<<"Stop camera..."<<endl; Camera.release(); //show time statistics time ( &timer_end ); /* get current time; same as: timer = time(NULL) */ double secondsElapsed = difftime ( timer_end,timer_begin ); cout<< secondsElapsed<<" seconds for "<< nCount<<" frames : FPS = "<< ( float ) ( ( float ) ( nCount ) /secondsElapsed ) <<endl; //save image cv::imwrite("raspicam_cv_image.jpg",image); cout<<"Image saved at raspicam_cv_image.jpg"<<endl; }
但是这也不是楼主想要的,因为是保存到磁盘上的jpg,我的腊鸡SD卡速度肯定很慢,下面是直接在内存中转化成jpg的方法:
int w=Camera.getWidth(),h=Camera.getHeight(); IplImage *pIpl = cvCreateImage(cvSize(w, h), 8, 3); //memcpy(pIpl->imageData, data, w * h * 3 * sizeof(char)); pIpl->imageData=(char*)data;//这里的data就是之前的bmp原始数据 cv::Mat tempMat=cv::cvarrToMat(pIpl); std::vector<uchar> buf; cv::imencode(".jpg",tempMat,buf);//也可以改为其他格式 dump((char*)&buf[0],buf.size(),"/root/Pictures/t.jpg"); delete[] data; data=nullptr; cvReleaseImage(&pIpl);//别忘记释放data和pIpl!!!
其中dump的代码是:
void dump(char *p, size_t len, const char *filename) { FILE *fp = fopen(filename, "w+b"); //fopen_s(&fp, filename, "w+b"); fwrite(p,sizeof(char),len,fp); fclose(fp); }
这样就完成了内存中图片的转化,楼主拍的照片是720*480分辨率的,转化为jpg基本都在50毫秒内,在树莓派上算是勉强能接受吧,具体其它用法在头文件里面很详细,各种参数都可以自己设置
转载请注明出处:http://blog.csdn.net/rtduq/article/details/79509720