Followup: Поиск точного «расстояние» между цветами

голоса
44

Оригинальный вопрос

Я ищу функцию, которая пытается количественно, как «дальний» (или различные) два цвета. Этот вопрос на самом деле из двух частей:

  1. Какого цвета пространство наилучшим образом представляет человеческое зрение?
  2. Какое расстояние метрики в этом пространстве наилучшим образом представляет человеческое зрение (евклидово?)
Задан 04/08/2008 в 16:08
источник пользователем
На других языках...                            


8 ответов

голоса
43

Преобразовать в La * B * (он же просто «Лаборатории», и вы также увидите ссылку на «CIELAB»). Хороший быстрый measaure разница цвета

(L1-L2) ^ 2 + (a1-a2) ^ 2 + (b1-b2) ^ 2

Цветовые ученые имеют другие более изощренные меры, которые могут быть не стоит беспокоиться, в зависимости от точности, необходимой для того, что вы делаете.

aИ bзначения представляют противоположные цвета таким образом , подобно тому , как работают колбочки, и может быть отрицательным или положительным. Нейтральные цвета - белый, серый есть a=0, b=0. LЭто яркость определяется определенным образом, от нуля (чистой темноты) до любой другой .

Сырая объяснение: >> Учитывая цвет, наши глаза различают два широких диапазонах длин волн - синих против более длинных волн. а затем, благодаря более недавней генетической мутации, более длинные длины волны конуса раздвоенным на два, отличающих нас красный против зеленого.

Кстати, это будет здорово для вашей карьеры, чтобы подняться над вашими цветовыми пещерными коллегами, которые знают только «RGB» или «CMYK», которые прекрасно подходит для устройств, но сосать для серьезной работы восприятия. Я работал для ученых изображений, которые не знали вещь об этом отеле!

Для большего удовольствия чтения по теории цвета разницы, попробуйте:

Более подробная информация о лаборатории в http://en.kioskea.net/video/cie-lab.php3 я не могу в это время найти не-уродливую страницу , которая на самом деле имела формулы преобразования , но я уверен , что кто - то будет редактировать это ответить включить один.

Ответил 16/09/2008 d 17:08
источник пользователем

голоса
8

в cmetric.htm ссылка выше не удалась для меня, а также многих других реализаций цветового расстояния я нашел (после очень долгого jurney ..) , как вычислить лучший цвет расстояние, и .. наиболее научно точный: DeltaE и от 2 (!) RGB значения с помощью OpenCV:

Это потребовало 3 преобразования цветового пространства + некоторое преобразование кода из JavaScript ( http://svn.int64.org/viewvc/int64/colors/colors.js ) на C ++

И, наконец, код (кажется, работает прямо из коробки, надеюсь, никто не находит серьезную ошибку там ... но мне кажется, прекрасно после ряда тестов)

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/photo/photo.hpp>
#include <math.h>

using namespace cv;
using namespace std;

#define REF_X 95.047; // Observer= 2°, Illuminant= D65
#define REF_Y 100.000;
#define REF_Z 108.883;

void bgr2xyz( const Vec3b& BGR, Vec3d& XYZ );
void xyz2lab( const Vec3d& XYZ, Vec3d& Lab );
void lab2lch( const Vec3d& Lab, Vec3d& LCH );
double deltaE2000( const Vec3b& bgr1, const Vec3b& bgr2 );
double deltaE2000( const Vec3d& lch1, const Vec3d& lch2 );


void bgr2xyz( const Vec3b& BGR, Vec3d& XYZ )
{
    double r = (double)BGR[2] / 255.0;
    double g = (double)BGR[1] / 255.0;
    double b = (double)BGR[0] / 255.0;
    if( r > 0.04045 )
        r = pow( ( r + 0.055 ) / 1.055, 2.4 );
    else
        r = r / 12.92;
    if( g > 0.04045 )
        g = pow( ( g + 0.055 ) / 1.055, 2.4 );
    else
        g = g / 12.92;
    if( b > 0.04045 )
        b = pow( ( b + 0.055 ) / 1.055, 2.4 );
    else
        b = b / 12.92;
    r *= 100.0;
    g *= 100.0;
    b *= 100.0;
    XYZ[0] = r * 0.4124 + g * 0.3576 + b * 0.1805;
    XYZ[1] = r * 0.2126 + g * 0.7152 + b * 0.0722;
    XYZ[2] = r * 0.0193 + g * 0.1192 + b * 0.9505;
}

void xyz2lab( const Vec3d& XYZ, Vec3d& Lab )
{
    double x = XYZ[0] / REF_X;
    double y = XYZ[1] / REF_X;
    double z = XYZ[2] / REF_X;
    if( x > 0.008856 )
        x = pow( x , .3333333333 );
    else
        x = ( 7.787 * x ) + ( 16.0 / 116.0 );
    if( y > 0.008856 )
        y = pow( y , .3333333333 );
    else
        y = ( 7.787 * y ) + ( 16.0 / 116.0 );
    if( z > 0.008856 )
        z = pow( z , .3333333333 );
    else
        z = ( 7.787 * z ) + ( 16.0 / 116.0 );
    Lab[0] = ( 116.0 * y ) - 16.0;
    Lab[1] = 500.0 * ( x - y );
    Lab[2] = 200.0 * ( y - z );
}

void lab2lch( const Vec3d& Lab, Vec3d& LCH )
{
    LCH[0] = Lab[0];
    LCH[1] = sqrt( ( Lab[1] * Lab[1] ) + ( Lab[2] * Lab[2] ) );
    LCH[2] = atan2( Lab[2], Lab[1] );
}

double deltaE2000( const Vec3b& bgr1, const Vec3b& bgr2 )
{
    Vec3d xyz1, xyz2, lab1, lab2, lch1, lch2;
    bgr2xyz( bgr1, xyz1 );
    bgr2xyz( bgr2, xyz2 );
    xyz2lab( xyz1, lab1 );
    xyz2lab( xyz2, lab2 );
    lab2lch( lab1, lch1 );
    lab2lch( lab2, lch2 );
    return deltaE2000( lch1, lch2 );
}

double deltaE2000( const Vec3d& lch1, const Vec3d& lch2 )
{
    double avg_L = ( lch1[0] + lch2[0] ) * 0.5;
    double delta_L = lch2[0] - lch1[0];
    double avg_C = ( lch1[1] + lch2[1] ) * 0.5;
    double delta_C = lch1[1] - lch2[1];
    double avg_H = ( lch1[2] + lch2[2] ) * 0.5;
    if( fabs( lch1[2] - lch2[2] ) > CV_PI )
        avg_H += CV_PI;
    double delta_H = lch2[2] - lch1[2];
    if( fabs( delta_H ) > CV_PI )
    {
        if( lch2[2] <= lch1[2] )
            delta_H += CV_PI * 2.0;
        else
            delta_H -= CV_PI * 2.0;
    }

    delta_H = sqrt( lch1[1] * lch2[1] ) * sin( delta_H ) * 2.0;
    double T = 1.0 -
            0.17 * cos( avg_H - CV_PI / 6.0 ) +
            0.24 * cos( avg_H * 2.0 ) +
            0.32 * cos( avg_H * 3.0 + CV_PI / 30.0 ) -
            0.20 * cos( avg_H * 4.0 - CV_PI * 7.0 / 20.0 );
    double SL = avg_L - 50.0;
    SL *= SL;
    SL = SL * 0.015 / sqrt( SL + 20.0 ) + 1.0;
    double SC = avg_C * 0.045 + 1.0;
    double SH = avg_C * T * 0.015 + 1.0;
    double delta_Theta = avg_H / 25.0 - CV_PI * 11.0 / 180.0;
    delta_Theta = exp( delta_Theta * -delta_Theta ) * ( CV_PI / 6.0 );
    double RT = pow( avg_C, 7.0 );
    RT = sqrt( RT / ( RT + 6103515625.0 ) ) * sin( delta_Theta ) * -2.0; // 6103515625 = 25^7
    delta_L /= SL;
    delta_C /= SC;
    delta_H /= SH;
    return sqrt( delta_L * delta_L + delta_C * delta_C + delta_H * delta_H + RT * delta_C * delta_H );
}

Надеюсь, что это поможет кому-то :)

Ответил 17/10/2013 d 02:39
источник пользователем

голоса
4

HSL и HSV лучше для человеческого восприятия цвета. Согласно Википедии :

Иногда предпочтительнее при работе с художественными материалами, оцифрованными изображениями или другими средствами массовой информации, использовать цветовую модель HSV или HSL над альтернативными моделями, такими как RGB или CMYK, из-за различия в способах модели подражать, как люди воспринимают цвет. RGB и CMYK являются аддитивными и вычитаемыми моделями, соответственно, моделируя таким образом, что первичные цветовые огни или пигменты (соответственно) объединяются, чтобы сформировать новые цвета при смешивании.

Графическое изображение HSV

Ответил 04/08/2008 d 16:16
источник пользователем

голоса
3

Статья Википедии о цветовых различиях перечислена ряд цветовых пространств и показателей расстояния , предназначенных согласовать с человеческим восприятием цвета расстояния.

Ответил 24/08/2008 d 16:38
источник пользователем

голоса
2

Как кто-то, кто дальтоник, я считаю, что это хорошо, чтобы попытаться добавить больше разделения затем нормальное зрение. Наиболее распространенная форма дальтонизма красный / зеленый дефицит. Это не означает, что вы не можете видеть красный или зеленый цвет, то это означает, что более трудно увидеть и более трудно увидеть различия. Таким образом, это занимает больше расстояние до цвета слепой человек может сказать разницу.

Ответил 16/09/2008 d 17:45
источник пользователем

голоса
2

Ну, как в первый момент вызова, я бы сказал , что из общих показателей HSV (Hue, Saturation и Value) или HSL лучше представитель того , как люди воспринимают цвета , чем говорить RGB или CYMK. См HSL, HSV в Википедии .

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

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

С точки зрения программиста зрения, вам нужно будет построить разностные векторы, но модифицированный матрицей пропорциональности, который будет регулировать длину соответственно в различных регионах HSL пространства - это было бы достаточно произвольным и будет основываться на различных идеях теории цвета, но быть переделаны довольно произвольно в зависимости от того, что вы хотите, чтобы применить это.

Еще лучше, если вы могли бы увидеть, если кто-то уже сделал такую ​​вещь в Интернете ...

Ответил 04/08/2008 d 16:37
источник пользователем

голоса
2

Простейшие расстояния , конечно , будет просто рассмотреть цвета , как 3D - векторы , происходящие из того же происхождения, и принимая расстояние между их конечными точками.

Если вам необходимо учитывать такие факторы, что зеленый является более заметным в оценке интенсивности, вы можете взвесить все значения.

ImageMagic предоставляет следующие масштабы:

  • красный: 0,3
  • зеленый: 0.6
  • синий: 0,1

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

Ответил 04/08/2008 d 16:14
источник пользователем

голоса
2

Может выглядеть как спам, но нет, эта связь действительно интересна для цветовых пространств :)

http://www.compuphase.com/cmetric.htm

Ответил 04/08/2008 d 16:14
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more