Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Изменение яркотсти цвета, Как изменить яркость цвета в RGB или HLS 
V
    Опции темы
masterik
Дата 22.1.2008, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 28.8.2006
Где: Остенд, Бельгия

Репутация: нет
Всего: нет



Доброго времени суток,


Очень срочно нужен алгоритм изменения яркости цвета в RGB пространстве... или на крайний случай в HSL/HSB пространстве.
Например имеется цвет RGB (255, 255, 128) - отсюда мне нужно получить два цвета: немного темнее и светлее имеюшегося...

Был бы рад увидеть не только формулу или кусок кода, но и парочку комментариев или ссылочку для прочтения...


Заранее очень благодарен за любую помощь

PM MAIL GTalk   Вверх
Earnest
Дата 24.1.2008, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 7
Всего: 183



Цитата(masterik @  22.1.2008,  18:15 Найти цитируемый пост)
отсюда мне нужно получить два цвета: немного темнее и светлее имеюшегося

Тогда тебе нужно не яркость менять, а интенсивность вроде. Пересчитываешь в HSL (или другое пространство, где оттенок в отдельную компоненту выделен), увеличиваешь или уменьшаешь компоненту, отвечающую зи интенсивность (или за светлоту), пересчитываешь обратно.
Для "немного светлее\темнее" у меня формул нет, есть именно для яркости\контрастности\интесивности (через YUV). Надо?
Вот еще здесь посмотри: http://www.easyrgb.com/math.php



--------------------
...
PM   Вверх
_Y_
Дата 25.1.2008, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1651
Регистрация: 27.11.2006

Репутация: 8
Всего: 34



Earnest, а мне тоже интересны формулы для яркости\контрастности\интесивности  smile 


--------------------
Я вот в этом поучаствовал: http://sbor-nik.appspot.com/kick.jsp?id=sbor5737960678883328 (на правах саморекламы:)
PM MAIL WWW   Вверх
dereyly
Дата 26.1.2008, 04:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 217
Регистрация: 16.6.2006

Репутация: 1
Всего: 4



можно возвести в степень или умножить =)
вроде степень увеличивает яркость, а умножение осветляет
Ну если неравномерная освещенность то нужно гистограмму(ы) анализировать выделять пики и растягивать (как то так)


PM MAIL   Вверх
masterik
Дата 31.1.2008, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 28.8.2006
Где: Остенд, Бельгия

Репутация: нет
Всего: нет



Цитата(Earnest @ 24.1.2008,  13:24)
Для "немного светлее\темнее" у меня формул нет, есть именно для яркости\контрастности\интесивности (через YUV). Надо?

Было бы интересно!

Нашел неплохие примеры конвертации между пространствами:
http://www.codeproject.com/KB/recipes/colorspace1.aspx
http://www.codeproject.com/KB/miscctrl/colorwheelv1.aspx


А нет формулы, чтобы прямо в RGB выполнить эту задачу, чтобы не терять время на переходы между пространствами?
PM MAIL GTalk   Вверх
Sardar
Дата 31.1.2008, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 1
Всего: 317



Если для человеческого глаза, то по идее (r, g, b) +- ([0.30, 0.59, 0.11] * (сколько нужно отнять/добавить)), отнимет именно от якрости, коэффициенты задают чувствительность человеческого глаза к исходной компоненте.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
TeAnton
Дата 2.2.2008, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 5.7.2007

Репутация: нет
Всего: нет



Если нужно быстро, и не нужен особо точный результат, можно просто каждый компонент RGB умножить на коэффициент. Коэффициент больше 1 осветляет, коэффициент меньше 1 затемняет. Дешево и сердито. Не забудь потом обработать переполнение через 255.
PM MAIL   Вверх
masterik
Дата 4.2.2008, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 28.8.2006
Где: Остенд, Бельгия

Репутация: нет
Всего: нет



Цитата(Sardar @ 31.1.2008,  16:18)
Если для человеческого глаза, то по идее (r, g, b) +- ([0.30, 0.59, 0.11] * (сколько нужно отнять/добавить)), отнимет именно от якрости, коэффициенты задают чувствительность человеческого глаза к исходной компоненте.

Спасибо, вот что у меня вышло:
Код

private Color SomeFunc(Color cc, double delta)
{
     int R = (int)System.Math.Min(System.Math.Max((double)cc.R + 0.30 * delta, 0.0), 255.0);
     int G = (int)System.Math.Min(System.Math.Max((double)cc.G + 0.59 * delta, 0.0), 255.0);
     int B = (int)System.Math.Min(System.Math.Max((double)cc.B + 0.11 * delta, 0.0), 255.0);
     return Color.FromArgb(R, G, B);
}


Правильно ли я понял, то что вы предложили?
Я получаю немного странные результаты... в каком диапозоне должен лежать коэффициент?
RGB компоненты должны быть в диапозоне [0,1] или [0,255]?

PM MAIL GTalk   Вверх
Earnest
Дата 5.2.2008, 10:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 7
Всего: 183



Цитата(_Y_ @  25.1.2008,  17:55 Найти цитируемый пост)
Earnest, а мне тоже интересны формулы для яркости\контрастности\интесивности 

Извините, давно не заглядывала. Вот формулы пересчета и коррекции яркости\контраста.
Все весьма несложно и работает вполне быстро.
Код

// Телевизионные пространства YUV, YIQ(NTSC)
// При построении модели пространства YIQ учитывалась особенность человеческого зрения:
// глаз человека в большей степени реагирует на яркостную составляющую и в меньшей степени
// на цветовые характеристики. При этом человеческий глаз по-разному воспринимает разные
// части спектра. На основании этого была предложена следующая схема пересчета из RGB в
// YIQ:
//      Y     0.299    0.587    0.114    R
//      I  =  0.596   -0.274   -0.322 *  G
//      Q     0.211   -0.522    0.311    B
// Обратный пересчет из YIQ в RGB осуществляется по формулам:
//      R     1    0.956    0.623    Y
//      G  =  1   -0.272   -0.648 *  I
//      B     1   -1.105    0.705    Q
// YUV:
//      Y = 0.299R + 0.587G + 0.114B;
//      U = (B - Y)/2.03;
//      V = (R – Y)/1.44.
// Обратный пересчет из YUV в RGB осуществляется по формулам:
//      R = Y + 1,44V;
//      G = Y – 0,37 – 0,73V;
//      B = Y + 2,03U.

    // изменения яркости, контраста, интенсивности
    struct CDelta
    {
        CDelta (int B = 0, int C = 0, int I = 0):
            m_B (B), m_C (C), m_I (I) {}
        int m_B, m_C, m_I;
    };


    struct CYuv
    {
        CYuv (CRgb rgb);
        operator CRgb() const;
        void Correct (const CDelta&);

        int m_Y, m_U, m_V;    
    };

    // используются те же самые формулы (только коэффициенты приведены к целому виду)
    inline CYuv::CYuv (CRgb clr)
    {
        // Y = 0.299R + 0.587G + 0.114B;
        m_Y = (30*clr.m_r + 59*clr.m_g + 11*clr.m_b)/100;
        // U = (B - Y)/2.03;
        m_U = (clr.m_b - m_Y) >> 1;
        // V = (R – Y)/1.44.
        m_V = (clr.m_r - m_Y)*25/36;
    }

    inline BYTE _Byte (int c)
    {
        return c < 0 ? 0 : c > 255 ? 255 : BYTE(c);
    }

    inline CYuv::operator CRgb () const
    {
        // R = Y + 1,44V;
        int R = (36*m_V/25 + m_Y);
        // B = Y + 2,03U.
        int B = (m_U << 1) + m_Y;
        // G = Y – 0,37 – 0,73V; ???
        int G = (100*m_Y - 11*B - 30*R)/59;

        return CRgb (_Byte(R), _Byte(G), _Byte(B));
    }
    
    inline void CYuv::Correct (const CDelta& delta)
    {
        static const int BaseY = 127;
        
      // BRIGHTNESS 
       m_Y += delta.m_B;
      
      // CONTRAST
      m_Y = (m_Y - BaseY) * delta.m_C/100 + BaseY;
      m_U = m_U * delta.m_C/100;
      m_V = m_V * delta.m_C/100;
      
      // INTENSITY
      m_U = m_U * delta.m_I/100;
      m_V = m_V * delta.m_I/100;
    }





--------------------
...
PM   Вверх
masterik
Дата 5.2.2008, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 30
Регистрация: 28.8.2006
Где: Остенд, Бельгия

Репутация: нет
Всего: нет



Sardar, Earnest, 

Большое вам спасибо за помощь!
Объеденив два ваших решения, которые очень схожи, получил нужный мне результат!

Так как пишу для PocketPC, где нет FPU, поэтому все вычисления с целыми числами!

Код

private Color _CorrectLightness(Color cc, int delta)
{
      int R = System.Math.Min(System.Math.Max(cc.R + delta * 30 / 100, 0), 255);
      int G = System.Math.Min(System.Math.Max(cc.G + delta * 59 / 100, 0), 255);
      int B = System.Math.Min(System.Math.Max(cc.B + delta * 11 / 100, 0), 255);
      return Color.FromArgb(R, G, B);
}

private void CalculateColors(Color orig_color)
{
     // Методом тыка получил то что мне нужно :)
     // Все же если цвет слишком светлый или темный
     // получаюься странные результаты...
     Color shadow = _CorrectLightness(orig_color, -80);
     Color dark = _CorrectLightness(orig_color, -40);
     Color normal = orig_color;
     Color light = _CorrectLightness(orig_color, 40);
     Color highlight = _CorrectLightness(orig_color, 80);

     // ......
}

PM MAIL GTalk   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Алгоритмы"

maxim1000

Форум "Алгоритмы" предназначен для обсуждения вопросов, связанных только с алгоритмами и структурами данных, без привязки к конкретному языку программирования и/или программному продукту.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, maxim1000.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Алгоритмы | Следующая тема »


 




[ Время генерации скрипта: 0.0529 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.