1.2 Графические фильтры: изменение яркости и контрастности изображения

Блоговая публикация пользователя: Alexei16 Эта публикация была перенесена из личного блога пользователя в общие разделы уровок сайта.
Необходимые знания:
Вам могут понадобится следующие статьи:
В этом уроке мы научимся изменять яркость и контрастность изображения.

Изменение яркости изображения

Яркость - это световая характеристика тел, отношение силы света, излучаемого поверхностью, к площади ее проекции на плоскости, перпендикулярной оси наблюдения. Если сказать проще, это количество белого цвета на изображении. Чем выше яркость, тем светлее оно становится.


Вот формула, по которой мы будем изменять яркость:

Код:
/*http://esate.ru, Alexei16*/

Pixel[X, Y] = Pixel[X, Y] + Brightness; 
//где Pixel[X, Y] – это цвет пикселя с координатами X, Y, а Brightness – это значение яркости.



Значения яркости находятся в диапазоне от 0 до 255. Для того чтобы яркость можно было уменьшать и увеличивать, значения яркости берут в диапазоне от -255 до 255, затем по формуле вычисляют цвет и приводят к диапазону от 0 до 255.

Чтобы цвет был в диапазоне от 0 до 255, мы будем использовать функцию ToByte().

Создайте класс Brightness и добавьте в него функцию ToByte().

Код:
/*http://esate.ru, Alexei16*/

private static byte ToByte(int Val)
{
    if (Val > 255) Val = 255;
    else if (Val < 0) Val = 0;
    return (byte)Val;
}


Теперь нужно добавить функцию ProcessImage:

Код:
/*http://esate.ru, Alexei16*/

public static unsafe Bitmap ProcessImage(Filter Main,int Value)
{
    for (int I = 0; I < Main.AllPixelsBytes; I += Main.BytesPerPixel)
    {
        *(Main.Unsafe_IMG_Scan0 + I + 0) = ToByte(*(Main.Unsafe_IMG_Scan0 + I + 0) + Value);//B
        *(Main.Unsafe_IMG_Scan0 + I + 1) = ToByte(*(Main.Unsafe_IMG_Scan0 + I + 1) + Value);//G   
        *(Main.Unsafe_IMG_Scan0 + I + 2) = ToByte(*(Main.Unsafe_IMG_Scan0 + I + 2) + Value);//R
    }
    Main.UnLock();
    return Main.Picture;
}


В этой функции мы к каждому пикселю прибавляли одинаковое значение и таким образом увеличивали яркость.


Использование в приложениях: яркость

Код:
/*http://esate.ru, Alexei16*/

Bitmap Test1 = Brightness.ProcessImage(new Filter(TestImage),85); //TestImage - это ваше изображение





Обработка изображений: изображение до изменения яркости Рисунок 1. Изображение до изменения яркости.
Обработка изображений: изображение после изменения яркости (+85) Рисунок 2. Изображение после изменения яркости (+85).

Изменение контрастности изображения

Контрастность - разница между оттенками цвета предмета наблюдения и окружающего его фона. Опять же, если сформулировать проще, это разница между различными расположенными рядом цветами. Чем выше контрастность, тем более резко мы наблюдаем переход от одного цвета к другому.

Реализация контрастности немного сложнее. Чтобы контрастность можно было увеличивать и уменьшать, её значения берут от -100 до 100, а потом уже значение приводят к диапазону от 0 до 255.

Формула ее вычисления выглядит следующим образом:

Код:
/*http://esate.ru, Alexei16*/

Contrast = (100.0 + Value) / 255.0; //Вычисляем общее значение
Contrast = Contrast * Contrast;
//Вычисляем контрастность для заданного пикселя
Pixel= RGB_Channels / 255.0;
Pixel = Pixel - 0.5;
Pixel = Pixel * Contrast;
Pixel = Pixel + 0.5;
Pixel = Pixel * 255;

if(Pixel > 255) Pixel = 255;
else if(Pixel < 0) Pixel = 0;


RGB_Channels здесь – это каналы RGB (красный, зелёный, синий).

Создайте класс Contrast и добавьте в него функцию ProcessImage :

Код:
/*http://esate.ru, Alexei16*/

public static unsafe Bitmap ProcessImage(Filter Main,int Value)
{
    int RedVal, GreenVal, BlueVal;
   
    double Pixel;
    double Contrast = (100.0 + Value) / 100.0; //Вычисляем общее значение контраста

    Contrast = Contrast * Contrast;

    for (int I = 0; I < Main.AllPixelsBytes; I += Main.BytesPerPixel)
    {
        BlueVal = *(Main.Unsafe_IMG_Scan0 + (I + 0)); //B
        GreenVal = *(Main.Unsafe_IMG_Scan0 + (I + 1)); //G 
        RedVal = *(Main.Unsafe_IMG_Scan0 + (I + 2)); //R

        Pixel = RedVal / 255.0;
        Pixel = Pixel - 0.5;
        Pixel = Pixel * Contrast;
        Pixel = Pixel + 0.5;
        Pixel = Pixel * 255;
        if (Pixel < 0) Pixel = 0;
        if (Pixel > 255) Pixel = 255;
        *(Main.Unsafe_IMG_Scan0 + (I + 2)) = Convert.ToByte(Pixel);

        Pixel = GreenVal / 255.0;
        Pixel = Pixel - 0.5;
        Pixel = Pixel * Contrast;
        Pixel = Pixel + 0.5;
        Pixel = Pixel * 255;
        if (Pixel < 0) Pixel = 0;
        if (Pixel > 255) Pixel = 255;
        *(Main.Unsafe_IMG_Scan0 + (I + 1)) = Convert.ToByte(Pixel);

        Pixel = BlueVal / 255.0;
        Pixel = Pixel - 0.5;
        Pixel = Pixel * Contrast;
        Pixel = Pixel + 0.5;
        Pixel = Pixel * 255;
        if (Pixel < 0) Pixel = 0;
        if (Pixel > 255) Pixel = 255;
        *(Main.Unsafe_IMG_Scan0 + (I + 0)) = Convert.ToByte(Pixel);
    }
    Main.UnLock();
    return Main.Picture;
}

Готово!

Использование в приложениях: контрастность

Код:
/*http://esate.ru, Alexei16*/

Bitmap Test1 = Contrast.ProcessImage(new Filter(TestImage),35); //TestImage - это ваше изображение





Обработка изображений: изображение до изменения контрастности (+35) Рисунок 3. Изображение до изменения контрастности.
Обработка изображений: изображение после изменения контрастности Рисунок 4. Изображение после изменения контрастности (+35).

Добавить комментарий
Расширенный режим добавления комментариев доступен на форуме: загрузка изображений, цитирование, форматирование текста, и т.д.
Ваше имя:
Текст сообщения:
^