[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; 
        } 
} 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM