[OpenCV开发]OpenCV图像编码和解码 imencode和imdecode使用,用于网络传输图片
在很多应用中,经常会直接把图片的二进制数据进行交换,比如说利用 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]=CV_IMWRITE_JPEG_QUALITY; |
| 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; |
| } |
| } |

浙公网安备 33010602011771号