gpt4 book ai didi

ffmpeg - YUV420p 中的 RGB32

转载 作者:行者123 更新时间:2023-12-04 23:06:14 26 4
gpt4 key购买 nike

我尝试将 rgb32 图像转换为 yuv420p 以录制视频。

我有图片

QImage image = QGuiApplication::primaryScreen()->grabWindow(0, rect_x, rect_y, rect_width, rect_height).toImage().convertToFormat(QImage::Format_RGB32);
AVFrame *frame;

并转换
for (y = 0; y < c->height; y++) {
QRgb *rowData = (QRgb*)image.scanLine(y);
for (x = 0; x < c->width; x++) {
QRgb pixelData = rowData[x];

int r = qRed(pixelData);
int g = qGreen(pixelData);
int b = qBlue(pixelData);

int y0 = (int)(0.2126 * (float)(r) + 0.7152 * (float)(g) + 0.0722 * (float)(b));
int u = 128 + (int)(-0.09991 * (float)(r) - 0.33609 * (float)(g) + 0.436 * (float)(b));
int v = 128 + (int)(0.615 * (float)(r) - 0.55861 * (float)(g) - 0.05639 * (float)(b));

frame->data[0][y * frame->linesize[0] + x] = y0;
frame->data[1][y / 2 * frame->linesize[1] + x / 2] = u;
frame->data[2][y / 2 * frame->linesize[2] + x / 2] = v;


}
}

但在结果图像上我看到了人工制品。文本看起来混合 http://joxi.ru/eAORRX0u4d46a2

转换 alogritm 中的这个错误还是其他什么?

UDP
for (y = 0; y < c->height; y++) {
QRgb *rowData = (QRgb*)image.scanLine(y);
for (x = 0; x < c->width; x++) {
QRgb pixelData = rowData[x];

int r = qRed(pixelData);
int g = qGreen(pixelData);
int b = qBlue(pixelData);

int y0 = (int)(0.2126 * (float)(r) + 0.7152 * (float)(g) + 0.0722 * (float)(b));

if (y0 < 0)
y0 = 0;
if (y0 > 255)
y0 = 255;


frame->data[0][y * frame->linesize[0] + x] = y0;
}
}

int x_pos = 0;
int y_pos = 0;

for (y = 1; y < c->height; y+=2) {
QRgb *pRow = (QRgb*)image.scanLine(y - 1);
QRgb *sRow = (QRgb*)image.scanLine(y);
for (x = 1; x < c->width; x+=2) {
QRgb pd1 = pRow[x - 1];
QRgb pd2 = pRow[x];
QRgb pd3 = sRow[x - 1];
QRgb pd4 = sRow[x];

int r = (qRed(pd1) + qRed(pd2) + qRed(pd3) + qRed(pd4)) / 4;
int g = (qGreen(pd1) + qGreen(pd2) + qGreen(pd3) + qGreen(pd4)) / 4;
int b = (qBlue(pd1) + qBlue(pd2) + qBlue(pd3) + qBlue(pd4)) / 4;

int u = 128 + (int)(-0.147 * (float)(r) - 0.289 * (float)(g) + 0.436 * (float)(b));
int v = 128 + (int)(0.615 * (float)(r) - 0.515 * (float)(g) - 0.1 * (float)(b));

if (u < 0)
u = 0;
if (v > 255)
v = 255;

frame->data[1][y_pos * frame->linesize[1] + x_pos] = u;
frame->data[2][y_pos * frame->linesize[2] + x_pos] = v;

x_pos++;
}

x_pos = 0;
y_pos++;
}

这对我有用,但速度很慢,一帧需要 60-70 毫秒

最佳答案

第一个问题是你让你的 YUV 值超出了允许的范围(甚至比 0x00..0xFF 更严格。但无论如何你都没有做任何限制)。 See :

Y' values are conventionally shifted and scaled to the range [16, 235] (referred to as studio swing or "TV levels") rather than using the full range of [0, 255] (referred to as full swing or "PC levels"). This confusing practice derives from the MPEG standards and explains why 16 is added to Y' and why the Y' coefficients in the basic transform sum to 220 instead of 255.[8] U and V values, which may be positive or negative, are summed with 128 to make them always positive, giving a studio range of 16–240 for U and V. (These ranges are important in video editing and production, since using the wrong range will result either in an image with "clipped" blacks and whites, or a low-contrast image.)



第二个问题是 4:2:0 意味着每个像素都有一个 Y 值,每四个像素有一个 U 值和一个 V 值。也就是说,U 和 V 应该是相应像素的平均值,并且您的循环只是用第四个输入像素的 U 和 V 覆盖值,而忽略前三个。

enter image description here

您用 标记了问题您之前的问题也与 FFmpeg 相关。请注意,FFmpeg 提供了 swscale 库,其中 sws_scale与您可以添加的循环和优化相比,转换方式更有效。请参阅有关 SO 的相关问题:
  • avcodec YUV to RGB
  • Video from pipe->YUV with libAV->RGB with sws_scale->Draw with Qt
  • 关于ffmpeg - YUV420p 中的 RGB32,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36059621/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com