简体   繁体   English

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

[英]Converting RGB image into 3 HSI outputs

Im trying to convert a RGB image into HSI where it comes in three different outputs; 我正在尝试将RGB图像转换为HSI,并在其中提供三个不同的输出。 Hue, saturation and intensity. 色相,饱和度和强度。

This is what I've done so far: 到目前为止,这是我所做的:

#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;
    }
}

I hope you guys can help me out! 我希望你们能帮助我! For now the output is 4 images, the RGB one and three HSI images, that is apparently not split up into the H, S and I value as mentioned. 目前,输出的是4幅图像,分别是RGB 1幅和3幅HSI图像,显然,它们并未像上述那样分成H,S和I值。

The usual terminology is channels . 通常的术语是渠道 An RGB image has 3 channels, Red, Green and Blue (actually B,G,R as you correctly noted). RGB图像具有3个通道,红色,绿色和蓝色(如您正确记述的,实际上是B,G,R)。 And an HSI image also has 3 channels, but different channels. HSI图像具有3个通道,但是通道不同。 But you're not creating one HSI image with 3 channels, you're creating 3 images with 3 channels. 但是,您不是在创建具有3个通道的HSI图像,而是在创建具有3个通道的3个图像。 They're obviously identical. 它们显然是相同的。

And how would imshow(i1) know that those 3 channels are supposed to form an HSI image? imshow(i1)怎么知道那三个通道应该构成一个HSI图像? Numbers are just numbers, and RGB or HSI are interpretations given to numbers. 数字只是数字,而RGB或HSI是对数字的解释。 imshow will display the first channel (H) as blue, etc. imshow会将第一个频道(H)显示为蓝色等。

You've to modify the following: 您必须修改以下内容:

//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;

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

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