图像的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...\n");
 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

图像DCT(离散余弦变换)是一种常用的图像压缩和编码算法。该算法将图像分成多个小块,对每个小块进行离散余弦变换,从而将图像从时域转换到频域。通过DCT变换,我们可以提取图像的频域特征,进而实现压缩和编码。 在MATLAB中,我们可以使用dct2函数来实现图像DCT变换。该函数接受一个矩阵作为输入,输出对应的DCT变换后的矩阵。首先,我们将图像分成大小相等的小块,然后对每个小块调用dct2函数进行DCT变换变换后的结果是一个与输入图像相同大小的矩阵。 例如,假设我们有一个大小为MxN的图像矩阵A,我们可以将图像分成大小为m×n的小块,其中m是M的因子,n是N的因子。然后,我们可以使用如下代码实现图像DCT变换: ```MATLAB [M, N] = size(A); m = M / m_factor; n = N / n_factor; dct_blocks = zeros(m, n, m_factor * n_factor); for i = 1 : m_factor for j = 1 : n_factor block = A((i - 1) * m + 1 : i * m, (j - 1) * n + 1 : j * n); dct_block = dct2(block); dct_blocks(:, :, (i - 1) * n_factor + j) = dct_block; end end ``` 最后,dct_blocks中的每个小块对应图像中的一个小区域,并且其中的每个小块都是经过DCT变换后的频域表示。我们可以使用这些小块来实现图像压缩、编码和其他图像处理操作。 总之,图像DCT变换是一种常用的图像压缩和编码算法,可以通过MATLAB的dct2函数实现。通过将图像分成多个小块并对每个小块进行DCT变换,我们可以提取图像的频域特征,并用于各种图像处理任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值