简体   繁体   English

按强度值,OpenCV标准化颜色通道和图像

[英]Normalizing color channels of and image by intensity values, OpenCV

I have split an image into 3 separate color channels - one blue, one green, and one red. 我将图像分成3个独立的颜色通道 - 一个蓝色,一个绿色和一个红色。 I would like to normalize each of these channels by the image's intensity, where intensity = (red + blue + green)/3. 我想通过图像的强度来标准化每个通道,其中强度=(红色+蓝色+绿色)/ 3。 To be clear, I am trying to make an image that is composed of one of the three color channels, divided by the image's intensity, where the intensity is described by the equation above. 为了清楚起见,我试图制作一个由三个颜色通道中的一个组成的图像,除以图像的强度,其中强度由上面的等式描述。 I am new to OpenCV and I do not think I am doing this correctly; 我是OpenCV的新手,我不认为我这样做是正确的; when the images are displayed, all the pixels appear to be black. 当显示图像时,所有像素看起来都是黑色的。 I am new to OpenCV (I have worked through the tutorials that come with the documentation, but that is it) - any advice about how to go about this normalization would be extremely helpful. 我是OpenCV的新手(我已经完成了文档附带的教程,但就是这样) - 关于如何进行这种规范化的任何建议都会非常有帮助。

Thanks! 谢谢!

Here is my attempt: 这是我的尝试:

int main(int argc, char** argv){
Mat sourceImage, I;
const char* redWindow = "Red Color Channel";
const char* greenWindow = "Green Color Channel";
const char* blueWindow = "Blue Color Channel";


if(argc != 2)
{
  cout << "Incorrect number of arguments" << endl;
}
/* Load the image */
sourceImage = imread(argv[1], 1);
if(!sourceImage.data)
{
  cout << "Image failed to load" << endl;
}

/* First, we have to allocate the new channels */
Mat r(sourceImage.rows, sourceImage.cols, CV_8UC1);
Mat b(sourceImage.rows, sourceImage.cols, CV_8UC1);
Mat g(sourceImage.rows, sourceImage.cols, CV_8UC1);

/* Now we put these into a matrix */
Mat out[] = {b, g, r};

/* Split the image into the three color channels */
split(sourceImage, out);

/* I = (r + b + g)/3  */
add(b, g, I);
add(I, r, I);
I = I/3;

Mat red = r/I;
Mat blue = b/I;
Mat green = g/I;

/* Create the windows */
namedWindow(blueWindow, 0);
namedWindow(greenWindow, 0);
namedWindow(redWindow, 0);

/* Show the images */
imshow(blueWindow, blue);
imshow(greenWindow, green);
imshow(redWindow, red);

waitKey(0);
return 0;
}

Once you divide by the intensity the pixel values will be in the range [0, 1], except since they are integers they will be 0 or 1. For a display image white is 255 and 0 is black, so this is why everything appears black to you. 一旦除以强度,像素值将在[0,1]范围内,除非它们是整数,它们将是0或1.对于显示图像,白色是255而0是黑色,所以这就是为什么一切都出现了黑到你。 You need to use floating point to get an accurate result, and you need to scale the result by 255 to see it. 您需要使用浮点来获得准确的结果,并且需要将结果缩放255以查看它。 Doing that results in this (which I an not sure is particularly useful) 这样做会导致这种情况(我不确定它特别有用)

在此输入图像描述 ( Image source: BSDS500 ) 图片来源:BSDS500

And here is the code that generated it: 以下是生成它的代码:

#include <opencv2/core/core.hpp>
#include <vector>   
int main(int argc, char** argv)
{
    // READ RGB color image and convert it to Lab
    cv::Mat bgr_image = cv::imread("208001.jpg"); // BSDS500 mushroom
    cv::imshow("original image", bgr_image);
    cv::Mat bgr_image_f;
    bgr_image.convertTo(bgr_image_f, CV_32FC3);

    // Extract the color planes and calculate I = (r + g + b) / 3
    std::vector<cv::Mat> planes(3);
    cv::split(bgr_image_f, planes); 

    cv::Mat intensity_f((planes[0] + planes[1] + planes[2]) / 3.0f);
    cv::Mat intensity;
    intensity_f.convertTo(intensity, CV_8UC1);
    cv::imshow("intensity", intensity);

    //void divide(InputArray src1, InputArray src2, OutputArray dst, double scale=1, int dtype=-1)
    cv::Mat b_normalized_f;
    cv::divide(planes[0], intensity_f, b_normalized_f);
    cv::Mat b_normalized;
    b_normalized_f.convertTo(b_normalized, CV_8UC1, 255.0);
    cv::imshow("b_normalized", b_normalized);

    cv::Mat g_normalized_f;
    cv::divide(planes[1], intensity_f, g_normalized_f);
    cv::Mat g_normalized;
    g_normalized_f.convertTo(g_normalized, CV_8UC1, 255.0);
    cv::imshow("g_normalized", g_normalized);

    cv::Mat r_normalized_f;
    cv::divide(planes[2], intensity_f, r_normalized_f);
    cv::Mat r_normalized;
    r_normalized_f.convertTo(r_normalized, CV_8UC1, 255.0);
    cv::imshow("r_normalized", r_normalized);
    cv::waitKey();
}

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

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