---恢复内容开始---
这里对图像的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 }
效果如下:
---恢复内容结束---