Algoholic.in.ua

Решения > RGB. Изменение цветового баланса изображения

RGB. Изменение цветового баланса изображения С++

Категория: Решения | Добавлено: 2015-12-12 | Просмотров: 348

Как Вам известно, каждое изображение в модели RGB состоит из точек, цвет которых определяется, учитывая три компонента - красный, зеленый и синий. Ниже мы рассмотрим, как определить и изменить диапазон оттенков каждой цветовой составляющей (минимальное и максимальное значение составляющей, между которыми располагаются значения абсолютно всех точек изображения).


Например, мы имеем изображение, в котором составляющая R каждого пикселя не привышает значения Rmax, а минимальное ее значение - Rmin. Если мы захотим изменить верхнюю (RmaxNew), или нижнюю (RminNew) границу составляющей R, то для пикселя P, который имеет значение компонента R = PR, мы получим значение PRNew, используя следующее уравнение (справедливо для всех каналов):


Изменение диапазонов оттенков изображения


Весь представленный ниже код написан на С++ под Visual Studio 2015 Community edition. Как разбить изображение на каналы, Вы можете увидеть здесь. В цикле, где каждый пиксель разбивается на составляющие, вызываем следующую функцию.


Функция вычисления диапазонов оттенков:

/*
Rmax, Rmin, Gmax, Gmin, Bmax, Bmin - глобальные переменные
*/
Byte Rmax = 255, Rmin = 0, Gmax = 255, Gmin = 0, Bmax = 255, Bmin = 0;
void RGBBounds(Byte R, Byte G, Byte B){
    if (R > Rmax)Rmax = R;	
    if (G > Gmax)Gmax = G;
    if (B > Bmax)Bmax = B;
    if (R < Rmin)Rmin = R;
    if (G < Gmin)Gmin = G;
    if (B < Bmin)Bmin = B;
}
        

После того, как все диапазоны определены, мы можем их изменить. Для этого используем уравнение, изображенное выше, а для удобства значения границ диапазонов изобразим в виде trackBar'ов и при событии MouseCaptureChanged будем вызывать функцию, которая пересчитает значения всех пикселей.


Функция изменения диапазона на примере канала R:

/*
Используем данную функцию для обеих trackBar'ов;
picR - изображение с красным каналом;
picNew - исходное изображение после изменения канала R;
start_image - контейнер с начальным изображением (PictureBox);
R[][] - глобальный двумерный массив, содержащий значение красных каналов всех пикселей начального изображения;
PRNew[][], PGNew[][], PBNew[][] - глобальные двумерные массивы, содержащие значения всех каналов всех пикселей измененного изображения;
labelMin, labelMax - label'ы со значениями границ.
*/        
void changeRed(){
	Bitmap^ picR = gcnew Bitmap(start_image->Image);
	Bitmap^ picNew = gcnew Bitmap(start_image->Image);
	RmaxNew = trackBar1->Value;
	RminNew = trackBar1->Value;
	for (int i = 0; i < picR->Width; i++)
		for (int j = 0; j < picR->Height; j++)
		{
			int a = fabsf(RmaxNew * (R[i][j] - Rmin));
			int b = fabsf(RminNew * (Rmax - R[i][j]));
			int c = fabsf(Rmax - Rmin);
			if (c != 0) PRNew[i][j] = (a + b) / c;
            else PRNew[i][j] = Rmax;
			picR->SetPixel(i, j, Color::FromArgb(PRNew[i][j], 0, 0));
			picNew->SetPixel(i, j, Color::FromArgb(PRNew[i][j], PGNew[i][j], PBNew[i][j]));
		}
	red_channel->Image = picR;
	finish_image->Image = picNew;
	labelMin->Text = RminNew.ToString();
	labelMax->Text = RmaxNew.ToString();
}
        

Результат:


Изменение диапазонов оттенков изображения


Изменение диапазонов оттенков изображения


Изменение диапазонов оттенков изображения


Яндекс.Метрика
Украина онлайн