【发布时间】:2018-12-12 12:24:18
【问题描述】:
我使用的逻辑是我正在读取缓冲区中的 yuv 文件并使用 3 个指针指向 Y、U、V 分量。图像尺寸为 1920*1080。
我是
- 为对应的 1U,1V 像素取 4 y 像素。
- 以整数形式提取像素值。
- 将 Y、U、V 转换为 R、G、B 并将分量存储在 RGB 缓冲区中。
但是视频输出不正确。输出有点像黑白
#include "stdafx.h"
#include <string>
#include <stdio.h>
unsigned char* g_pcRGBbuffer;
unsigned char* g_pcYUVBuffer;
int _tmain(int argc, _TCHAR* argv[])
{
int l_nSize = 1920 * 1080 * 1.5;
g_pcYUVBuffer = new unsigned char[l_nSize];
g_pcRGBbuffer = new unsigned char[1920 * 1080 * 3];
FILE* fp_source;
FILE* fp_rgb = NULL;
int l_nY, l_nU, l_nV;
double l_dR, l_dG, l_dB, l_ni;
fp_source = fopen("D:\\Sample_1920x1080.yuv", "rb");
// converting yuv file to rgb file
if (fp_source)
{
fp_rgb = fopen("D:\\Sample_1920x1080.rgb", "wb+");
while (!feof(fp_source))
{
fread(g_pcYUVBuffer, 1, l_nSize, fp_source);
unsigned char* l_pcY = g_pcYUVBuffer;
unsigned char* l_pcU = l_pcY + 1920 * 1080;
unsigned char* l_pcV = l_pcU + ((1920 * 1080) / 4);
unsigned char* l_pcRGBbuffer = g_pcRGBbuffer;
for (l_ni = 0; l_ni < (1920 * 1080) / 4; l_ni++)
{
l_nY = l_pcY[0];
l_nU = l_pcU[0];
l_nV = l_pcV[0];
l_dR = l_nY + 1.402 * (l_nV - 128);
l_dG = l_nY - 0.34414 * (l_nU - 128) - 0.71414 * (l_nV - 128);
l_dB = l_nY + 1.772 * (l_nU - 128);
// This prevents colour distortions in rgb image
if (l_dR < 0)
l_dR = 0;
else if (l_dR > 255)
l_dR = 255;
if (l_dG < 0)
l_dG = 0;
else if (l_dG > 255)
l_dG = 255;
if (l_dB < 0)
l_dB = 0;
else if (l_dB > 255)
l_dB = 255;
// 1st pixel of RGB
l_pcRGBbuffer[0] = l_dR;
l_pcRGBbuffer[1] = l_dG;
l_pcRGBbuffer[2] = l_dB;
l_nY = l_pcY[1];
l_nU = l_pcU[0];
l_nV = l_pcV[0];
l_dR = l_nY + 1.402 * (l_nV - 128);
l_dG = l_nY - 0.34414 * (l_nU - 128) - 0.71414 * (l_nV - 128);
l_dB = l_nY + 1.772 * (l_nU - 128);
if (l_dR < 0)
l_dR = 0;
else if (l_dR > 255)
l_dR = 255;
if (l_dG < 0)
l_dG = 0;
else if (l_dG > 255)
l_dG = 255;
if (l_dB < 0)
l_dB = 0;
else if (l_dB > 255)
l_dB = 255;
// 2nd pixel of RGB
l_pcRGBbuffer[3] = l_dR;
l_pcRGBbuffer[4] = l_dG;
l_pcRGBbuffer[5] = l_dB;
l_nY = l_pcY[2];
l_nU = l_pcU[0];
l_nV = l_pcV[0];
l_dR = l_nY + 1.402 * (l_nV - 128);
l_dG = l_nY - 0.34414 * (l_nU - 128) - 0.71414 * (l_nV - 128);
l_dB = l_nY + 1.772 * (l_nU - 128);
if (l_dR < 0)
l_dR = 0;
else if (l_dR > 255)
l_dR = 255;
if (l_dG < 0)
l_dG = 0;
else if (l_dG > 255)
l_dG = 255;
if (l_dB < 0)
l_dB = 0;
else if (l_dB > 255)
l_dB = 255;
// 3rd pixel of RGB
l_pcRGBbuffer[6] = l_dR;
l_pcRGBbuffer[7] = l_dG;
l_pcRGBbuffer[8] = l_dB;
l_nY = l_pcY[3];
l_nU = l_pcU[0];
l_nV = l_pcV[0];
// l_dR = 1.164*(l_nY-16 ) + 1.596*(l_nV-128 );
// l_dG = 1.164*(l_nY-16 ) - 0.813*(l_nV-128 ) - 0.391*(l_nU-128);
// l_dB = 1.164*(l_nY-16 ) + 2.018*(l_nU-128 );
l_dR = l_nY + 1.402 * (l_nV - 128);
l_dG = l_nY - 0.34414 * (l_nU - 128) - 0.71414 * (l_nV - 128);
l_dB = l_nY + 1.772 * (l_nU - 128);
if (l_dR < 0)
l_dR = 0;
else if (l_dR > 255)
l_dR = 255;
if (l_dG < 0)
l_dG = 0;
else if (l_dG > 255)
l_dG = 255;
if (l_dB < 0)
l_dB = 0;
else if (l_dB > 255)
l_dB = 255;
// 4th pixel of RGB
l_pcRGBbuffer[9] = l_dR;
l_pcRGBbuffer[10] = l_dG;
l_pcRGBbuffer[11] = l_dB;
l_pcY += 4;
l_pcU += 1;
l_pcV += 1;
l_pcRGBbuffer += 12;
}
fwrite(g_pcRGBbuffer, 1, 1920 * 1080 * 3, fp_rgb);
}
printf("Video converted to rgb file \n ");
}
else
{
printf("fail\n");
}
fclose(fp_rgb);
fclose(fp_source);
return 0;
}
【问题讨论】:
-
与其将所有公式和所有钳位在 0..255 范围内重复三次,不如考虑将其编写为一个函数,这样您就无需更正和维护。此外,与其说
if(fopen...)和缩进然后if(open...)并再次缩进,恕我直言,如果您在知道出现问题后立即退出函数,即@ 987654324@ -
你检查过你的 YUV 文件的布局,还是你猜它是 4 个一组的?通常首先出现所有 Y 值,然后是二次采样的 U,然后是 V 值...
-
我的 yuv 文件是 4:2:0 平面格式,所以我假设每个 1U 和 1V 会有四个 4y 像素。因为 y 像素的数量是 u 和 v.am i 的 4 倍指向 l_pcY,l_pcU,l_pcV 的正确位置??
-
如果是平面的,所有的 Y 像素都在前,然后是所有的 U 像素,然后是所有的 V 像素。您愿意分享您的文件吗?
-
嗨,OP。我已经通过自动格式化程序运行您的代码并修复了帖子中的格式,因此所有代码都显示为代码。我还修正了你的语法并添加了 c++ 标签。如果你只用 c++11 标记它,人们就不太可能看到你的帖子。如果您使用 c++11 标记帖子,通常也应该使用 c++ 标记它。
标签: c++ c++11 image-processing video-processing file-handling