Нормализация цветовых каналов и изображения по значениям интенсивности, OpenCV

Я разделил изображение на 3 отдельных цветовых канала — один синий, один зеленый и один красный. Я хотел бы нормализовать каждый из этих каналов по интенсивности изображения, где интенсивность = (красный + синий + зеленый) / 3. Чтобы быть ясным, я пытаюсь сделать изображение, которое состоит из одного из трех цветовых каналов, разделенных на интенсивность изображения, где интенсивность описывается уравнением выше.
Я новичок в OpenCV, и я не думаю, что я делаю это правильно; когда изображения отображаются, все пиксели выглядят черными.
Я новичок в OpenCV (я работал с учебными пособиями, которые поставляются с документацией, но это все) — любой совет о том, как выполнить эту нормализацию, был бы чрезвычайно полезен.

Спасибо!

Вот моя попытка:

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

2

Решение

Как только вы поделите на интенсивность, значения пикселей будут в диапазоне [0, 1], за исключением того, что они являются целыми числами, они будут 0 или 1. Для отображаемого изображения белый 255, а 0 черный, поэтому все и появляется черный для вас.
Вам нужно использовать число с плавающей запятой, чтобы получить точный результат, и вам нужно масштабировать результат на 255, чтобы увидеть его.
Это приводит к этому (что я не уверен, особенно полезно)

введите описание изображения здесь
(Источник изображения: BSDS500)

И вот код, который его сгенерировал:

#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();
}
3

Другие решения