樓主最近在做一個人臉識別的項目,剛好有個一個樹莓派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