将 RGB 图像转换为 3 个 HSI 输出

Posted

技术标签:

【中文标题】将 RGB 图像转换为 3 个 HSI 输出【英文标题】:Converting RGB image into 3 HSI outputs 【发布时间】:2017-10-24 10:38:02 【问题描述】:

我正在尝试将 RGB 图像转换为 HSI,它有三种不同的输出;色相、饱和度和强度。

这是我到目前为止所做的:

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;

int main() 
    //This line of code interts the picture of a cat 

    float r, g, b, h, s, in;

    Mat image;
    image = imread("C:/Users/pjusk/Desktop/kitti.jpg");

    if (image.data && !image.empty()) 
        imshow("Hello world!", image);

        Mat h1(image.rows, image.cols, image.type());
        Mat s1(image.rows, image.cols, image.type());
        Mat i1(image.rows, image.cols, image.type());

        float r, g, b, h, s, in;

        for (int i = 0; i < image.rows; i++)
        
            for (int j = 0; j < image.cols; j++)
            
                b = image.at<Vec3b>(i, j)[0];
                g = image.at<Vec3b>(i, j)[1];
                r = image.at<Vec3b>(i, j)[2];

                in = (b + g + r) / 3;

                float min_val = 0;
                min_val = std::min(r, std::min(b, g));

                s = 1 - 3 * (min_val / (b + g + r));
                if (s < 0.00001)
                
                    s = 0;
                
                else if (s > 0.99999) 
                    s = 1;
                

                if (s != 0)
                
                    h = 0.5 * ((r - g) + (r - b)) / sqrt(((r - g)*(r - g)) + ((r - b)*(g - b)));
                    h = acos(h);

                    if (b <= g)
                    
                        h = h;
                    
                    else 
                        h = ((360 * 3.14159265) / 180.0) - h;
                    
                


                h1.at<Vec3b>(i, j)[2] = (h * 180) / 3.14159265;
                h1.at<Vec3b>(i, j)[1] = s * 100;
                h1.at<Vec3b>(i, j)[0] = in;

                s1.at<Vec3b>(i, j)[2] = (h * 180) / 3.14159265;
                s1.at<Vec3b>(i, j)[1] = s * 100;
                s1.at<Vec3b>(i, j)[0] = in;

                i1.at<Vec3b>(i, j)[2] = (h * 180) / 3.14159265;
                i1.at<Vec3b>(i, j)[1] = s * 100;
                i1.at<Vec3b>(i, j)[0] = in;
            
        


        imshow("h1 image", h1);
        imshow("s1 image", s1);
        imshow("i1 image", i1);


        waitKey(0);
        return 0;
    

希望大家能帮帮我! 目前输出的是 4 张图像,RGB 1 和 3 张 HSI 图像,显然没有像前面提到的那样分为 H、S 和 I 值。

【问题讨论】:

【参考方案1】:

通常的术语是渠道。 RGB 图像有 3 个通道,红色、绿色和蓝色(实际上是 B、G、R,正如您正确指出的那样)。而 HSI 图像有 3 个通道,但通道不同。但是您不是在创建一个具有 3 个通道的 HSI 图像,而是在创建具有 3 个通道的 3 个图像。它们显然是相同的。

imshow(i1) 怎么知道这 3 个通道应该形成 HSI 图像?数字只是数字,RGB 或 HSI 是对数字的解释。 imshow 会将第一个通道 (H) 显示为蓝色等。

【讨论】:

【参考方案2】:

您必须修改以下内容:

//The h, s and i images should be of type CV_8UC1
Mat h1(image.rows, image.cols, CV_8UC1);
Mat s1(image.rows, image.cols, CV_8UC1);
Mat i1(image.rows, image.cols, CV_8UC1);

//Since h1 is a one channel image, s and l should not be added
h1.at<uchar>(i, j) = (h * 180) / 3.14159265;
//h1.at<Vec3b>(i, j)[1] = s * 100;
//h1.at<Vec3b>(i, j)[0] = in;

//Since s1 is a one channel image, h and l should not be added
//s1.at<Vec3b>(i, j)[2] = (h * 180) / 3.14159265;
s1.at<uchar>(i, j) = s * 100;
//s1.at<Vec3b>(i, j)[0] = in;

//Since i1 is a one channel image, h and s should not be added
//i1.at<Vec3b>(i, j)[2] = (h * 180) / 3.14159265;
//i1.at<Vec3b>(i, j)[1] = s * 100;
i1.at<uchar>(i, j) = in;

【讨论】:

以上是关于将 RGB 图像转换为 3 个 HSI 输出的主要内容,如果未能解决你的问题,请参考以下文章

C: 将数组转换为 RGB 图像

使用 OpenCV 从 android Camera2 将 YUV 转换为 RGB ImageReader 时出现问题,输出图像为灰度

RGB、CMY、CMYK、YUV、HSV、HSI、LAB颜色空间详解

Opencv函数

将numpy数组转换为rgb图像

opencv中cvCvtColor函数在哪个库