[OpenCV開發]OpenCV影象編碼和解碼 imencode和imdecode使用,用於網路傳輸圖片
阿新 • • 發佈:2019-02-01
在很多應用中,經常會直接把圖片的二進位制資料進行交換,比如說利用 socket 通訊傳送圖片二進位制資料,或者直接用記憶體資料庫(例如 Redis)來傳遞圖片二進位制資料。
這個時候,當你的應用程式讀到記憶體裡的二進位制圖片資料時,怎麼樣直接轉為 OpenCV 可以使用的圖片格式呢,答案是用 cv::imdecode 這個函式:
std::vector<char> data(lpData, size); cv::Mat image = cv::imdecode(cv::Mat(data), 1); IplImage qImg; qImg = IplImage(image); //cv::Mat -> IplImage
即先構造一個 char 字串序列的 vector,用來儲存圖片的二進位制資料,然後再轉為 cv::Mat 成為可以被 cv::imdecode 使用的資料格式,然後直接型別轉換為 IplImage 資料格式。
同樣,如果你需要把 IplImage 或 cv::Mat 壓縮並寫到一段記憶體塊裡時,就需要使用 cv::imencode 這個函式,使用方法類似。
示例程式碼如下:
#include<iostream> |
#include<fstream> |
#include<cv.h> |
#include<highgui.h> |
usingnamespace std; |
usingnamespace cv; |
double getPSNR(Mat& src1,Mat& src2,int bb=0); |
int main(int argc,char** argv) |
{ |
Mat src= imread("lenna.png"); |
//(1) jpeg compression |
vector<uchar> buff;//buffer for coding |
vector<int> param= vector<int>(2); |
param[0]= |
param[1]=95;//default(95) 0-100 |
imencode(".jpg",src,buff,param); |
cout<<"coded file size(jpg)"<<buff.size()<<endl;//fit buff size automatically. |
Mat jpegimage= imdecode(Mat(buff),CV_LOAD_IMAGE_COLOR); |
//(2) png compression |
param[0]=CV_IMWRITE_PNG_COMPRESSION; |
param[1]=3;//default(3) 0-9. |
imencode(".png",src,buff,param); |
cout<<"coded file size(png)"<<buff.size()<<endl; |
Mat pngimage= imdecode(Mat(buff),CV_LOAD_IMAGE_COLOR); |
//(3) intaractive jpeg compression |
char name[64]; |
namedWindow("jpg"); |
int q=95; |
createTrackbar("quality","jpg",&q,100); |
int key=0; |
while(key!='q') |
{ |
param[0]=CV_IMWRITE_JPEG_QUALITY; |
param[1]=q; |
imencode(".jpg",src,buff,param); |
Mat show= imdecode(Mat(buff),CV_LOAD_IMAGE_COLOR); |
double psnr= getPSNR(src,show);//get PSNR |
double bpp=8.0*buff.size()/(show.size().area());//bit/pixe; |
sprintf(name,"quality:%03d, %.1fdB, %.2fbpp",q,psnr,bpp); |
putText(show,name,Point(15,50), FONT_HERSHEY_SIMPLEX,1,CV_RGB(255,255,255),2); |
imshow("jpg",show); |
key = waitKey(33); |
if(key=='s') |
{ |
//(4) data writing |
sprintf(name,"q%03d_%.2fbpp.png",q,bpp); |
imwrite(name,show); |
sprintf(name,"q%03d_%.2fbpp.jpg",q,bpp); |
param[0]=CV_IMWRITE_JPEG_QUALITY; |
param[1]=q; |
imwrite(name,src,param);; |
} |
} |
} |
double getPSNR(Mat& src1,Mat& src2,int bb) |
{ |
int i,j; |
double sse,mse,psnr; |
sse =0.0; |
Mat s1,s2; |
cvtColor(src1,s1,CV_BGR2GRAY); |
cvtColor(src2,s2,CV_BGR2GRAY); |
int count=0; |
for(j=bb;j<s1.rows-bb;j++) |
{ |
uchar* d=s1.ptr(j); |
uchar* s=s2.ptr(j); |
for(i=bb;i<s1.cols-bb;i++) |
{ |
sse +=((d[i]- s[i])*(d[i]- s[i])); |
count++; |
} |
} |
if(sse==0.0|| count==0) |
{ |
return0; |
} |
else |
{ |
mse =sse/(double)(count); |
psnr =10.0*log10((255*255)/mse); |
return psnr; |
} |
} |