天天看點

【opencv】【圖像壓縮】opencv下的DCT變換壓縮圖像

#include "stdafx.h"
#include<iostream>  
#include<sstream>
//#include <opencv2/core/core.hpp>  
//#include <opencv2/highgui/highgui.hpp>  
//#include<math.h>
//#include <opencv.h>
#include <opencv2/opencv.hpp>
#include <cv.h>
#include <string.h>
double T = ;


using namespace cv;
using namespace std;

int main()
{
    // 讀入一張圖檔(遊戲原畫)  
    Mat src = imread("sw1.png");
    resize(src,src,Size(src.cols/*,src.rows/*));
    imshow("Origin Image", src);
    int h = src.rows;
    int w = src.cols;

    //Mat yuvimg = src.clone();
    //從BGR空間轉換到YUV空間(也可以不轉換,直接在RGB空間)      
    Mat yuvimg(src.size(), CV_8UC3);
    cvtColor(src, yuvimg, CV_BGR2YUV); //定義YUV空間圖像為yuvimage    
    Mat dst(src.size(), CV_64FC3);     //定義輸出圖像為dst    

                                       //分割YUV通道    
    vector<Mat> channels;
    split(yuvimg, channels);

    //提取YUV顔色空間各通道      
    Mat Y = channels.at(); imshow("Y image", Y);
    Mat U = channels.at(); imshow("U image", U);
    Mat V = channels.at(); imshow("V image", V);
    //waitKey(0);
    //DCT系數的三個通道    
    //Mat DCTY(src.size(), CV_64FC1);
    //Mat DCTU(src.size(), CV_64FC1);
    //Mat DCTV(src.size(), CV_64FC1);
    Mat DCTY(yuvimg.size(), CV_64FC1);
    Mat DCTU(yuvimg.size(), CV_64FC1);
    Mat DCTV(yuvimg.size(), CV_64FC1);
    //DCT變換    
    dct(Mat_<double>(Y), DCTY,);
    dct(Mat_<double>(U), DCTU,);
    dct(Mat_<double>(V), DCTV,);

    //Y通道壓縮      
    for (int i = ; i < h; i++)
    {
        double *p = DCTY.ptr<double>(i);
        for (int j = ; j < w; j++)
        {
            if (abs(p[j]) < T)
                p[j] = ;
        }
    }

    //U通道壓縮      
    for (int i = ; i < h; i++)
    {
        double *p = DCTU.ptr<double>(i);
        for (int j = ; j < w; j++)
        {
            if (abs(p[j]) < T)
                p[j] = ;
        }
    }

    //V通道壓縮      
    for (int i = ; i < h; i++)
    {
        double *p = DCTV.ptr<double>(i);
        for (int j = ; j < w; j++)
        {
            if (abs(p[j]) < T)
                p[j] = ;
        }
    }
    Mat dstY(src.size(), CV_64FC1);
    Mat dstU(src.size(), CV_64FC1);
    Mat dstV(src.size(), CV_64FC1);

    //DCT逆變換    
    idct(DCTY, dstY);
    idct(DCTU, dstU);
    idct(DCTV, dstV);

    //merge方式1    
    //Mat planes[] = { Mat_<uchar>(dstB), Mat_<uchar>(dstG), Mat_<uchar>(dstR) };    
    //merge(planes, 3, yuvimg);     
    //cvtColor(yuvimg, dst, CV_YUV2BGR);    

    //merge方式2    
    channels.at() = Mat_<uchar>(dstY);
    channels.at() = Mat_<uchar>(dstU);
    channels.at() = Mat_<uchar>(dstV);
    merge(channels, yuvimg);

    //将壓縮後圖像從YUV空間重新轉換到BGR空間    
    cvtColor(yuvimg, dst, CV_YUV2BGR);

    imshow("Recoverd Y image", Mat_<uchar>(dstY));
    imshow("Recoverd U image", Mat_<uchar>(dstU));
    imshow("Recoverd V image", Mat_<uchar>(dstV));
    imshow("DstImage", dst);
    stringstream s;
    s<<T;
    string t=s.str();
    imwrite(string("DstImage")+t+".png",dst);
    waitKey();
    return ;
}