简体   繁体   English

使用C ++在OpenCV中实现Matlab函数'rgb2ntsc'

[英]Implementation of Matlab function 'rgb2ntsc' in OpenCV using C++

I am trying to implement Matlab function 'rgb2ntsc' in OpenCV using C++. 我正在尝试使用C ++在OpenCV中实现Matlab函数'rgb2ntsc'。

According to Matlab: YIQ = rgb2ntsc(RGB), RGB is a input colour image. 根据Matlab:YIQ = rgb2ntsc(RGB),RGB是输入彩色图像。

在此处输入图片说明

Matrix multiplication in OpenCV using C++ has some criteria: 使用C ++的OpenCV中的矩阵乘法有一些条件:

1) same number of channels for each matrix (2 channel or 1 channel) 2) matrix should be in float values 1)每个矩阵的通道数相同(2个通道或1个通道)2)矩阵的浮点值

So how can I multiply my input color image(input has 3channels) with NTSC components? 那么如何将输入的彩色图像(输入具有3个通道)与NTSC分量相乘?

You should use the Vec3f type from OpenCV (which is actually a 3x1 matrix): 您应该使用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;

--- EDIT --- -编辑-

Here is a better version, converting a whole image using only OpenCV features 这是一个更好的版本,仅使用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);

Not sure if I am right, but YIQ has 3 values the same as RGB, so pictures remain 3 channel. 不确定我是否正确,但是YIQ具有3个与RGB相同的值,因此图片保持3个通道。

If you multiplicate float with float or integer, you get float, so I don't see the problem with multiplication. 如果将float与float或integer相乘,则会得到float,因此我看不到乘法的问题。 Maybe I cannot understand your problem correctly. 也许我无法正确理解您的问题。 Multiplication of above should be: 上面的乘积应该是:

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

and so on in my opinion. 在我看来,依此类推。

If RGB is in integer representation you may think of something like: 如果RGB以整数表示,您可能会想到以下内容:

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

to convert it to float. 将其转换为浮点数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM