【问题标题】:Implementation of Matlab function 'rgb2ntsc' in OpenCV using C++使用 C++ 在 OpenCV 中实现 Matlab 函数 'rgb2ntsc'
【发布时间】:2015-11-28 06:35:08
【问题描述】:

我正在尝试使用 C++ 在 OpenCV 中实现 Matlab 函数“rgb2ntsc”。

根据 Matlab: YIQ = rgb2ntsc(RGB),RGB为输入彩色图像。

OpenCV 中使用 C++ 的矩阵乘法有一些标准:

1) 每个矩阵的通道数相同(2 通道或 1 通道) 2) 矩阵应该是浮点值

那么如何将我的输入彩色图像(输入有 3 个通道)与 NTSC 分量相乘?

【问题讨论】:

  • 不要使用矩阵乘法。只需将YIQ 的每个方程分解为RGB 之间的权重之和,然后将每个结果堆叠成一个3 通道矩阵。看看下面的答案以获得洞察力。

标签: c++ matlab opencv image-processing


【解决方案1】:

您应该使用 OpenCV 中的 Vec3f 类型(实际上是一个 3x1 矩阵):

// I assume you have RGB values as unsigned char in [0-255] interval
// here using a dummy color
unsigned char R = 255;
unsigned char G = 127;
unsigned char B = 64;

// construct a Vec3f from those, divide by 255 to get them in [0-1] interval
Vec3f colorRGB(R/255.0f, G/255.0f, B/255.0f);

// matrix for RGB -> YIQ conversion
Matx33f matYIQ( 0.299f,  0.587f,  0.114f,
                0.596f, -0.274f, -0.322f,
                0.211f, -0.523f,  0.312f);

// do the conversion
// a warning ... I & Q can be negative
// Y => [0,1]
// I => [-1,1]
// Q => [-1,1]
Vec3f colorYIQ = matYIQ * colorRGB;

--- 编辑---

这是一个更好的版本,仅使用 OpenCV 功能转换整个图像

// let's define the matrix for RGB -> YIQ conversion
Matx33f matYIQ( 0.299f,  0.587f,  0.114f,
                0.596f, -0.274f, -0.322f,
                0.211f, -0.523f,  0.312f);

// I assume you have a source image of type CV_8UC3 
// CV_8UC3: 3 channels, each on unsigned char, so [0,255]
// here is a dummy one, black by default, 256x256
Mat ImgRGB_8UC3(256, 256, CV_8UC3);

// We need to convert this to a new image of type CV_32FC3
// CV_32FC3: 3 channels each on 32bit float [-inf, +inf]
// we need to do this because YIQ result will be in [-1.0, 1.0] (I & Q)
// so this obviously cannot be stored in CV_8UC3
// At the same time, we will also divide by 255.0 to put values in [0.0, 1.0]
Mat ImgYIQ_32FC3;
ImgRGB_8UC3.convertTo(ImgYIQ_32FC3, CV_32FC3, 1.0/255.0);

// at this point ImgYIQ_32FC3 contains pixels made of 3 RGB float components in [0-1]
// so let's convert to YIQ
// (cv::transform will apply the matrix to each 3 component pixel of ImgYIQ_32FC3)
cv::transform(ImgYIQ_32FC3, ImgYIQ_32FC3, matYIQ);

【讨论】:

  • 如何以简洁的方式对整个图像进行此操作?此代码仅对单个 RGB 像素(不是 OP 顺便说一句)执行转换。
  • @rayryeng:我添加了一些应该这样做的代码(未测试)
  • 哦,太好了。 :)
【解决方案2】:

不确定我是否正确,但 YIQ 有 3 个值与 RGB 相同,所以图片保持 3 通道。

如果你将浮点数与浮点数或整数相乘,你会得到浮点数,所以我看不出乘法的问题。也许我无法正确理解您的问题。上面的乘法应该是:

Y = 0.299*R+0.587*G+0.114*B,
I = 0.596*R-0.274*G-0.322*B,

在我看来等等。

如果 RGB 是整数表示,您可能会想到类似:

template<typename intType>
float convertIntToFloat(intType number){
    return (1.0/std::numeric_limits<intType>::max())*number;
}

将其转换为浮点数。

【讨论】:

    猜你喜欢
    • 2013-07-13
    • 1970-01-01
    • 2014-05-28
    • 2023-03-22
    • 2014-03-30
    • 1970-01-01
    • 2016-06-27
    • 1970-01-01
    相关资源
    最近更新 更多