gpt4 book ai didi

c++ - BGR -> YCbCr 转换工作不正常

转载 作者:行者123 更新时间:2023-11-28 01:20:09 26 4
gpt4 key购买 nike

我正在尝试将图像从 RBG(OpenCV 中的 BGR)手动转换为 YCbCr 色彩空间。

我的图像是一张 png 彩色图像,宽度为 800,高度为 600,3 个 channel ,16 位深度。

这是我尝试解决这个问题的方法。

cv::Mat convertToYCbCr(cv::Mat image) {                                         
// converts an RGB image to YCbCr
// cv::Mat: B-G-R
std::cout << "Converting image to YCbCr color space." << std::endl;
int i, j;
for (i = 0; i <= image.cols; i++) {
for (j = 0; j <= image.rows; j++) {

// R, G, B values
auto R = image.at<cv::Vec3d>(j, i)[2];
auto G = image.at<cv::Vec3d>(j, i)[1];
auto B = image.at<cv::Vec3d>(j, i)[0];

// Y'
auto Y = image.at<cv::Vec3d>(j,i)[0] = 0.299 * R + 0.587 * G + 0.114 * B + 16;

// Cb
auto Cb = image.at<cv::Vec3d>(j,i)[1] = 128 + (-0.169 * R -0.331 * G + 0.5 * B);

// Cr
auto Cr = image.at<cv::Vec3d>(j,i)[2] = 128 + (0.5 * R -0.419 * G -0.081 * B);
std::cout << "At conversion: Y = " << Y << ", Cb = " << Cb << ", "
<< Cr << std::endl;
}
}
std::cout << "Converting finished." << std::endl;
return image;
}

我收到的图像是这样的:

Result Image

我期待的是这个(使用 OpenCV 方法):

enter image description here

垂直线可能暗示了什么?我的循环错了吗?我什至可以用 YCbCr 值“替换”RGB 值并期望图像看起来像示例吗? typeid() 为两个图像返回相同的值,N2cv3MatE

最佳答案

观察到错误结果的主要原因是用于访问图像的数据类型不正确。访问 16 位无符号像素的正确类型是 cv::Vec3w(不是 cv::Vec3d)。

下一个问题是用于转换的系数是为模拟信号 (YPbPr) 设计的。对于数字图像,我们必须使用为数字图像设计的系数 ( YCbCr )。您可以在 Wikipedia article on YCbCr 上找到更多详细信息在 ITU-R BT.601 转换部分。

文章中缺少的一条信息是,如果图像是 16 位无符号深度或 32 位浮点深度,系数将如何变化?答案是我们必须根据图像的位深度缩放系数。

对于 16 位无符号深度的图像,缩放应按如下方式执行:

auto Y = (R * 65.481f * scale) + (G * 128.553f * scale) + (B * 24.966f * scale) + (16.0f * offset);
auto Cb = (R * -37.797f * scale) + (G * -74.203f * scale) + (B * 112.0f * scale) + (128.0f * offset);
auto Cr = (R * 112.0f * scale) + (G * -93.786f * scale) + (B * -18.214f * scale) + (128.0f * offset);

其中 scale 等于 257.0/65535.0offset 等于 257.0

此转换技术已从 rgb2ycbcr 的 MATLAB 源代码中采用引用以下描述缩放比例的书的函数:

C.A. Poynton, "A Technical Introduction to Digital Video", John Wiley & Sons, Inc., 1996, Chapter 9, Page 175`

既然转换已经完成,我们面临的第三个问题就是类似于OpenCV的图像可视化。当我们使用 OpenCV 执行颜色转换时,输出图像以 YCrCb 顺序存储,而不是通常的 YCbCr。因此,要使用我们的自定义转换逻辑获得相同的图像,我们必须以相关顺序存储值。

示例转换代码可能如下所示:

if(image.type() == CV_16UC3)
{
const float scale = 257.0f / 65535.0f;
const float offset = 257.0f;
for (int i = 0; i < image.cols; i++)
{
for (int j = 0; j < image.rows; j++)
{
auto R = image.at<cv::Vec3w>(j, i)[2];
auto G = image.at<cv::Vec3w>(j, i)[1];
auto B = image.at<cv::Vec3w>(j, i)[0];

auto Y = (R * 65.481f * scale) + (G * 128.553f * scale) + (B * 24.966f * scale) + (16.0f * offset);
auto Cb = (R * -37.797f * scale) + (G * -74.203f * scale) + (B * 112.0f * scale) + (128.0f * offset);
auto Cr = (R * 112.0f * scale) + (G * -93.786f * scale) + (B * -18.214f * scale) + (128.0f * offset);

image.at<cv::Vec3w>(j, i)[0] = (unsigned short)Y;
image.at<cv::Vec3w>(j, i)[1] = (unsigned short)Cr;
image.at<cv::Vec3w>(j, i)[2] = (unsigned short)Cb;
}
}
}

关于c++ - BGR -> YCbCr 转换工作不正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56725115/

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