计算两段yuv格式视频流中每一帧的psnr值

现在虚拟视点生成了yuv格式的视频流,如何计算每一帧的psnr值,进行了如下步骤:

1.对yuv视频流进行转换为jpg图片;

2.把jpg图片转化为avi视频流,便于批处理;

3.对avi视频中的每一帧计算psnr值。

程序:

[cpp]  view plain  copy
  1. #include <stdlib.h>  
  2. #include <stdio.h>  
  3. #include <math.h>  
  4. #include <cv.h>  
  5. #include <highgui.h>  
  6. #define NUM_FRAME 100 //只处理前100帧,根据视频帧数可修改  
  7. void CalcPsnr(const char *in1,const char *in2)  
  8. {  
  9.     cv::VideoCapture vc1;  
  10.     cv::VideoCapture vc2;  
  11.     bool flag1 = vc1.open(in1);  
  12.     bool flag2 = vc2.open(in2);  
  13.     if (!flag1||!flag2)  
  14.     {  
  15.         printf("avi file open error \n");  
  16.         system("pause");  
  17.         exit(-1);  
  18.     }  
  19.   
  20.     int frmCount1 = vc1.get(CV_CAP_PROP_FRAME_COUNT);  
  21.     int frmCount2 = vc2.get(CV_CAP_PROP_FRAME_COUNT);  
  22.     printf("frmCount: %d \n", frmCount1);  
  23.     printf("frmCount: %d \n", frmCount2);  
  24.     for (int i = 0; i < frmCount1; i++)  
  25.     {  
  26.         printf("%d/%d \n", i + 1, frmCount1);  
  27.         cv::Mat image_ref;  
  28.         vc1 >> image_ref;  
  29.         cv::Mat image_obj;  
  30.         vc2 >> image_obj;  
  31.         double mse = 0;  
  32.         double div_r = 0;  
  33.         double div_g = 0;  
  34.         double div_b = 0;  
  35.         int width = image_ref.cols;  
  36.         int height = image_ref.rows;  
  37.         double psnr = 0;  
  38.         for (int v = 0; v < height; v++)  
  39.         {  
  40.             for (int u = 0; u < width; u++)  
  41.             {  
  42.                 div_r = image_ref.at<cv::Vec3b>(v, u)[0] - image_obj.at<cv::Vec3b>(v, u)[0];  
  43.                 div_g = image_ref.at<cv::Vec3b>(v, u)[1] - image_obj.at<cv::Vec3b>(v, u)[1];  
  44.                 div_b = image_ref.at<cv::Vec3b>(v, u)[2] - image_obj.at<cv::Vec3b>(v, u)[2];  
  45.                 mse += ((div_r*div_r + div_b*div_b + div_g*div_g) / 3);  
  46.   
  47.             }  
  48.         }  
  49.         mse = mse / (width*height);  
  50.         psnr = 10 * log10(255 * 255 / mse);  
  51.         printf("%lf\n", mse);  
  52.         printf("%lf\n", psnr);  
  53.     }  
  54.     return;  
  55. }  
  56. void DisplayYUV2RGB(const char *dir,const char *in,int _w,int _h)  
  57. {  
  58.     int w = _w;  
  59.     int h = _h;  
  60.     printf("yuv file w: %d, h: %d \n", w, h);  
  61.     FILE* pFileIn = fopen(in, "rb+");  
  62.     int bufLen = w*h * 3 / 2;  
  63.     unsigned char* pYuvBuf = new unsigned char[bufLen];  
  64.     int iCount = 0;  
  65.   
  66.   
  67.     for (int i = 0; i<NUM_FRAME; i++)  
  68.     {  
  69.         fread(pYuvBuf, bufLen*sizeof(unsigned char), 1, pFileIn);  
  70.   
  71.         cv::Mat yuvImg;  
  72.         yuvImg.create(h * 3 / 2, w, CV_8UC1);  
  73.         memcpy(yuvImg.data, pYuvBuf, bufLen*sizeof(unsigned char));  
  74.         cv::Mat rgbImg;  
  75.         cv::cvtColor(yuvImg, rgbImg, CV_YUV2BGR_I420);  
  76.   
  77.         cv::imshow("img", rgbImg);  
  78.         char s[100];  
  79.         sprintf(s,"%spic%d%s",dir,i,".jpg");  
  80.         cv::imwrite(s, rgbImg);  
  81.         cv::waitKey(1);  
  82.   
  83.         printf("%d \n", iCount++);  
  84.     }  
  85.     delete[] pYuvBuf;  
  86.     fclose(pFileIn);  
  87. }  
  88. void Image_to_video(const char* in, const char* out)  
  89. {  
  90.     int num = 1;  
  91.     CvSize size = cvSize(1024, 768);  //视频帧格式的大小  
  92.     double fps = 30; //每秒钟的帧率  
  93.     CvVideoWriter *writer = cvCreateVideoWriter(out, CV_FOURCC('D''I''V''X'), fps, size); //创建视频文件  
  94.     char cname[100];  
  95.     sprintf(cname, in, num); //加载图片的文件夹,图片的名称编号是1开始1,2,3,4,5.。。。  
  96.     IplImage *src = cvLoadImage(cname);  
  97.     if (!src)  
  98.     {  
  99.         return;  
  100.     }  
  101.     IplImage *src_resize = cvCreateImage(size, 8, 3); //创建视频文件格式大小的图片  
  102.     cvNamedWindow("avi");  
  103.     while (src)  
  104.     {  
  105.         cvShowImage("avi", src_resize);  
  106.         cvWaitKey(1);  
  107.         cvResize(src, src_resize); //将读取的图片设置为视频格式大小相同  
  108.         cvWriteFrame(writer, src_resize); //保存图片为视频流格式  
  109.         cvReleaseImage(&src); //释放空间  
  110.         num++;  
  111.         sprintf(cname, in, num);  
  112.         src = cvLoadImage(cname);       //循环读取数据  
  113.     }  
  114.     cvReleaseVideoWriter(&writer);  
  115.     cvReleaseImage(&src_resize);  
  116. }  
  117. int main(int argc, char *argv[])  
  118. {  
  119.     const char *out = "C:/Users/jiang/Desktop/output/book_virtual08.yuv";  
  120.     const char *dir = "C:/Users/jiang/Desktop/output/tupian1/";  
  121.     DisplayYUV2RGB(dir, out, 1024, 768);  
  122.     const char *outImagename = "C:/Users/jiang/Desktop/output/tupian1/pic%d.jpg";  
  123.     const char *outVideoname = "C:/Users/jiang/Desktop/output/3outfile.avi";  
  124.     Image_to_video(outImagename, outVideoname);  
  125.   
  126.     out = "C:/Users/jiang/Desktop/bookarrival/bookarrival_c_8.yuv";  
  127.     dir = "C:/Users/jiang/Desktop/output/tupian1/";  
  128.     DisplayYUV2RGB(dir, out, 1024, 768);  
  129.     outImagename = "C:/Users/jiang/Desktop/output/tupian1/pic%d.jpg";  
  130.     outVideoname = "C:/Users/jiang/Desktop/output/4outfile.avi";  
  131.     Image_to_video(outImagename, outVideoname);  
  132.   
  133.     const char *in1 = "C:/Users/jiang/Desktop/output/3outfile.avi";  
  134.     const char *in2 = "C:/Users/jiang/Desktop/output/4outfile.avi";  
  135.     CalcPsnr(in1, in2);  
  136.   
  137.     getchar();  
  138. }  


文章标签:  视频流 批处理 视频 psnr
个人分类:  虚拟视点

猜你喜欢

转载自blog.csdn.net/liangjiubujiu/article/details/80631541
今日推荐