图像的DCT变换

---恢复内容开始---

这里对图像的YUV至RGB变换,使用opencv的函数cvDCT直接进行处理:

其变换公式如下:

用VS2015进行代码的处理效果,显示YUV各通道的图像:

  1 #include "highgui.h"
  2 #include <math.h>
  3 #include <cv.h>
  4 #include "cxcore.h"
  5 #define cvCvtPlaneToPix cvMerge 
  6 double PSNR_B = 0;
  7 double PSNR_G = 0;
  8 double PSNR_R = 0;
  9 double PSNR;
 10 
 11 
 12 int main(int argc, char* argv[])
 13 {
 14     const char* imagename = "F:/c/59.jpg";
 15     IplImage *src;
 16     CvScalar SrcPixel;
 17     CvScalar DstPixel;
 18     double sumB = 0;
 19     double sumG = 0;
 20     double sumR = 0;
 21     double mseB;
 22     double mseG;
 23     double mseR;
 24 
 25     src = cvLoadImage(imagename, 1);
 26     if (!src)
 27     {
 28         printf("can't open the image...
");
 29         return -1;
 30     }
 31     // YUV颜色空间   
 32     IplImage* YUVImage = cvCreateImage(cvSize(src->width, src->height), src->depth, 3);
 33     IplImage* dst = cvCreateImage(cvSize(src->width, src->height), src->depth, 3);
 34     // YUV颜色空间各通道   
 35     IplImage* Y = cvCreateImage(cvSize(src->width, src->height), IPL_DEPTH_8U, 1);
 36     IplImage* U = cvCreateImage(cvSize(src->width, src->height), IPL_DEPTH_8U, 1);
 37     IplImage* V = cvCreateImage(cvSize(src->width, src->height), IPL_DEPTH_8U, 1);
 38 
 39 
 40     //cvNamedWindow( "Origin Image", CV_WINDOW_AUTOSIZE );   
 41     cvCvtColor(src, YUVImage, CV_BGR2YUV); //BGR→YUV   
 42     cvSplit(YUVImage, Y, U, V, NULL);//分割通道   
 43 
 44     CvMat* MatY = cvCreateMat(Y->height, Y->width, CV_64FC1);
 45     CvMat* MatU = cvCreateMat(V->height, U->width, CV_64FC1);
 46     CvMat* MatV = cvCreateMat(V->height, V->width, CV_64FC1);
 47 
 48     CvMat* DCTY = cvCreateMat(Y->height, Y->width, CV_64FC1);
 49     CvMat* DCTU = cvCreateMat(U->height, U->width, CV_64FC1);
 50     CvMat* DCTV = cvCreateMat(V->height, V->width, CV_64FC1);
 51 
 52     cvScale(Y, MatY);
 53     cvScale(U, MatU);
 54     cvScale(V, MatV);
 55 
 56     cvDCT(MatY, DCTY, CV_DXT_FORWARD); //余弦变换   
 57     cvDCT(MatU, DCTU, CV_DXT_FORWARD); //余弦变换   
 58     cvDCT(MatV, DCTV, CV_DXT_FORWARD); //余弦变换   
 59 
 60                                        //Y 通道压缩   
 61     for (int i = 0; i < Y->height; i++)
 62     {
 63         for (int j = 0; j < Y->width; j++)
 64         {
 65             double  element = CV_MAT_ELEM(*DCTY, double, i, j);
 66             if (abs(element) < 10)
 67                 CV_MAT_ELEM(*DCTY, double, i, j) = 0;
 68         }
 69     }
 70 
 71     // U 通道压缩   
 72     for (int i = 0; i < U->height; i++)
 73     {
 74         for (int j = 0; j < U->width; j++)
 75         {
 76             double  element = CV_MAT_ELEM(*DCTU, double, i, j);
 77             if (abs(element) < 20)
 78                 CV_MAT_ELEM(*DCTU, double, i, j) = 0;
 79         }
 80     }
 81 
 82     // V 通道压缩   
 83     for (int i = 0; i < V->height; i++)
 84     {
 85         for (int j = 0; j < V->width; j++)
 86         {
 87             double  element = CV_MAT_ELEM(*DCTV, double, i, j);
 88             if (abs(element) < 20)
 89                 CV_MAT_ELEM(*DCTV, double, i, j) = 0;
 90         }
 91     }
 92     cvDCT(DCTY, MatY, CV_DXT_INVERSE); //余弦反变换   
 93     cvDCT(DCTU, MatU, CV_DXT_INVERSE);
 94     cvDCT(DCTV, MatV, CV_DXT_INVERSE);
 95 
 96     cvScale(MatY, Y);
 97     cvScale(MatU, U);
 98     cvScale(MatV, V);
 99 
100     cvMerge(Y, U, V, NULL, YUVImage);
101     cvCvtColor(YUVImage, dst, CV_YUV2BGR); //YUV→BGR   
102 
103                                            //  计算前后两幅图像的PSNR值   
104     for (int i = 0; i < src->height; i++)
105     {
106         for (int j = 0; j < src->width; j++)
107         {
108             SrcPixel = cvGet2D(src, i, j);
109             DstPixel = cvGet2D(dst, i, j);
110             sumB += (SrcPixel.val[0] - DstPixel.val[0]) * (SrcPixel.val[0] - DstPixel.val[0]);
111             sumG += (SrcPixel.val[1] - DstPixel.val[1]) * (SrcPixel.val[1] - DstPixel.val[1]);
112             sumR += (SrcPixel.val[2] - DstPixel.val[2]) * (SrcPixel.val[2] - DstPixel.val[2]);
113 
114         }
115     }
116     mseB = sumB / ((src->width) * (src->height)); //计算均方差   
117     mseG = sumG / ((src->width) * (src->height));
118     mseR = sumR / ((src->width) * (src->height));
119 
120     PSNR_B = 10.0 * (log10(255.0 * 255.0 / mseB));
121     PSNR_G = 10.0 * (log10(255.0 * 255.0 / mseG));
122     PSNR_R = 10.0 * (log10(255.0 * 255.0 / mseR));
123     PSNR = (PSNR_B + PSNR_G + PSNR_R) / 3;
124     printf("PSNR:%d ", PSNR_B);
125     cvShowImage("YImage", Y);
126     cvShowImage("UImage", U);
127     cvShowImage("VImage", V);
128     cvShowImage("DstImage", dst);
129     cvSaveImage("F:/dstdemo.jpg", dst);
130 
131     while (1)
132     {
133         if (cvWaitKey(0) == 27) break;
134     }
135 
136     cvDestroyWindow("YImage");
137     cvDestroyWindow("UImage");
138     cvDestroyWindow("VImage");
139     cvDestroyWindow("DstImage");
140 
141 
142     cvReleaseImage(&Y);
143     cvReleaseImage(&U);
144     cvReleaseImage(&V);
145     cvReleaseImage(&src);
146     cvReleaseImage(&dst);
147     cvReleaseImage(&YUVImage);
148     system("pause");
149     return 0;
150 }

效果如下:

---恢复内容结束---

转载请说明出处!
原文地址:https://www.cnblogs.com/zengshangzhi/p/8277548.html