gpt4 book ai didi

directx-11 - 使用 DirectX11 像素着色器将 BGRA 转换为 YUV444 的绿色图像

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

enter image description here
我是 HLSL 的新手。我正在尝试使用纹理作为渲染目标将使用 DXGI 桌面复制 API 捕获的图像的颜色空间从 BGRA 转换为 YUV444。
我已将像素着色器设置为执行所需的转换。并从渲染目标纹理中获取 4:2:0 子采样 YUV 并使用 ffmpeg 将其编码为 H264,我可以看到图像。
问题是 - 它是 greenish .
着色器的输入颜色信息是浮点数据类型,但可用于 RGB 到 YUV 转换的系数矩阵采用整数颜色信息。
如果我使用钳位函数并从输入颜色中取出整数,我将失去准确性。
欢迎任何建议和指导。如果任何其他信息有帮助,请告诉我。
我怀疑我写的像素着色器,因为我是第一次使用它。这是像素着色器。

float3 rgb_to_yuv(float3 RGB)
{
float y = dot(RGB, float3(0.29900f, -0.16874f, 0.50000f));
float u = dot(RGB, float3(0.58700f, -0.33126f, -0.41869f));
float v = dot(RGB, float3(0.11400f, 0.50000f, -0.08131f));
return float3(y, u, v);
}
float4 PS(PS_INPUT input) : SV_Target
{
float4 rgba, yuva;
rgba = tx.Sample(samLinear, input.Tex);
float3 ctr = float3(0, 0, .5f);
return float4(rgb_to_yuv(rgba.rgb) + ctr, rgba.a);
}

渲染目标映射到 CPU 可读纹理并将 YUV444 数据复制到 3 BYTE 数组中并提供给 ffmpeg libx264 编码器。
编码器将编码后的数据包写入视频文件。
在这里,我为每个 2X2 像素矩阵取一个 U(Cb) 和一个 V(Cr) 以及 4 个 Y 值。
我从纹理中检索 yuv420 数据为:

for (size_t h = 0, uvH = 0; h < desc.Height; ++h)
{
for (size_t w = 0, uvW = 0; w < desc.Width; ++w)
{
dist = resource1.RowPitch *h + w * 4;
distance = resource.RowPitch *h + w * 4;
distance2 = inframe->linesize[0] * h + w;
data = sptr[distance + 2 ];
pY[distance2] = data;
if (w % 2 == 0 && h % 2 == 0)
{
data1 = sptr[distance + 1];
distance2 = inframe->linesize[1] * uvH + uvW++;
pU[distance2] = data1;
data1 = sptr[distance ];
pV[distance2] = data1;
}
}
if (h % 2)
uvH++;
}

EDIT1:添加混合状态 desc :
D3D11_BLEND_DESC BlendStateDesc;
BlendStateDesc.AlphaToCoverageEnable = FALSE;
BlendStateDesc.IndependentBlendEnable = FALSE;
BlendStateDesc.RenderTarget[0].BlendEnable = TRUE;
BlendStateDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
BlendStateDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
BlendStateDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
BlendStateDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
BlendStateDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO;
BlendStateDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
BlendStateDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
hr = m_Device->CreateBlendState(&BlendStateDesc, &m_BlendState);
FLOAT blendFactor[4] = {0.f, 0.f, 0.f, 0.f};
m_DeviceContext->OMSetBlendState(nullptr, blendFactor, 0xffffffff);
m_DeviceContext->OMSetRenderTargets(1, &m_RTV, nullptr);
m_DeviceContext->VSSetShader(m_VertexShader, nullptr, 0);
m_DeviceContext->PSSetShader(m_PixelShader, nullptr, 0);
m_DeviceContext->PSSetShaderResources(0, 1, &ShaderResource);
m_DeviceContext->PSSetSamplers(0, 1, &m_SamplerLinear);
m_DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

EDIT2:在 CPU 上计算时的 Y U V 值:45 200 170 和涉及浮点计算的像素着色器后的值:86 141 104。
对应的 R G B:48 45 45. 有什么不同?

最佳答案

看起来您的矩阵已转置。

根据 [6.4] ITU.BT-601 Y'CbCr 下的 www.martinreddy.net/gfx/faqs/colorconv.faq:

Y'= 0.299*R' + 0.587*G' + 0.114*B'
Cb=-0.169*R' - 0.331*G' + 0.500*B'
Cr= 0.500*R' - 0.419*G' - 0.081*B'

您在复制的源代码中误解了 numpy.dot 的行为。

此外,看起来@harold 是正确的,您应该同时抵消 U 和 V。

关于directx-11 - 使用 DirectX11 像素着色器将 BGRA 转换为 YUV444 的绿色图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47285651/

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