[OpenCV开发]OpenCV图像编码和解码 imencode和imdecode使用,用于网络传输图片

摘要:
类似地,如果需要压缩IplImage或cv::Mat并将其写入内存块,则需要以类似的方式使用cv::imencode函数。

在很多应用中,经常会直接把图片的二进制数据进行交换,比如说利用 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; 
        } 
} 

免责声明:文章转载自《[OpenCV开发]OpenCV图像编码和解码 imencode和imdecode使用,用于网络传输图片》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇docker 安装 nacos/nacos-server 镜像并配置本地数据库使用goaccess对Nginx日志简单分析下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

H.264基本原理与编码流程

H264视频压缩算法现在无疑是所有视频压缩技术中使用最广泛,最流行的。随着 x264/openh264以及ffmpeg等开源库的推出,大多数使用者无需再对H264的细节做过多的研究,这大降低了人们使用H264的成本。 但为了用好H264,我们还是要对H264的基本原理弄清楚才行。今天我们就来看看H264的基本原理。 H264概述 H264压缩技术主要采用...

工具软件 PYUV打开raw图片

引自:http://blog.csdn.net/lavenderss/article/details/51495648  [pYUV]如何打开YUV/RGB图片 pYUV工具本身使用起来比较简单,但如果选项设置错误,会导致图像显示失真或错误,让人误以为是图片本身的问题,这里介绍两个比较典型类型的图片打开方式,其他类型图片打开方式触类旁通即可。 1.  ...

java中远程http文件上传及file2multipartfile

    工作中有时会遇到各种需求,你得变着法儿去解决,当然重要的是在什么场景中去完成。 比如Strut2中file类型如何转换成multipartfile类型,找了几天,发现一个变通的方法记录如下(虽然最后没有用上。。): 1 private static MultipartFile getMulFileByPath(String picPath) {...

攻防世界-web-i-got-id-200(perl文件上传+ARGV造成任意文件读取和任意命令执行)

题目来源:csaw-ctf-2016-quals 题目描述:嗯。。我刚建好了一个网站 进入场景后有3个链接,点进去都是.pl文件,.pl文件都是用perl编写的网页文件。 尝试后发现,Files链接可以上传文件并把文件内容打印出来。猜想后台应该用了param()函数。 param()函数会返回一个列表的文件但是只有第一个文件会被放入到下面的接收变量中。如...

记录yii2-imagine几个常用方法

记录yii2-imagine几个常用方法:      //压缩 Image::thumbnail('@webroot/img/test-image.jpg', 120, 120)->save(Yii::getAlias('@webroot/img/thumb-test-image.jpg'), ['quality' => 100...

c++实现md5加密

最近发现md5加密算法挺有趣,特点是单向加密不可逆,加密后的字符串长度相等,于是就用C++尝试实现了一下 头文件定义 1 /* 2 ******************************************************* 3 * brief: md5 encryption 4 * author: Monkey.Knight...