İzleyen: renkler arasında doğru bir "mesafe" bulma

oy
44

Orijinal Soru

Ben uzak (ya da ayrı) iki renklerin ne kadar ölçmek için çalışan bir işlev için arıyorum. Bu soru iki kısımda gerçekten:

  1. Ne renk uzayı iyi insan vizyonu temsil?
  2. Bu alanda metrik Ne mesafesi iyi insan görme (Öklit?) temsil
Oluştur 04/08/2008 saat 16:08
kaynak kullanıcı
Diğer dillerde...                            


8 cevaplar

oy
43

La * b * dönüştür (aka sadece düz "Lab" ve ayrıca "CIELAB" referans görürsünüz). renk farkı İyi bir hızlı measaure olduğunu

(L1-L2) ^ 2 + (A1-A2) ^ 2 + (B1-B2) ^ 2

Renk bilim adamları ne yaptığınızı için gerekli hassasiyeti bağlı olarak rahatsız değer olmayabilir diğer daha rafine önlemler var.

aVe bdeğerler koniler nasıl benzer bir şekilde karşıt renk temsil eder ve negatif veya pozitif olabilir. Nötr renkler - beyaz, griler vardır a=0, b=0. LNe olursa olsun kadar sıfır (tamamen karanlık) gelen özel bir şekilde tanımlanmış parlaklığı.

Ham açıklama: - uzun dalga boylarına karşı mavi >> Bir renk göz önüne alındığında, gözlerimiz dalga boyu iki geniş aralıklar arasında ayrım. ve sonra, daha yeni genetik mutasyon sayesinde, daha uzun dalga boyu konileri yeşil vs kırmızı bizim için ayırt ikiye içine çatal.

Kariyer cihazlar için mükemmeldir ancak "RGB" veya "CMYK" biliyor renk mağara adamı Meslektaşlarımız üzerinde yükselecek ama ciddi algı çalışmaları için emmek için Bu arada, bu harika olacak. Bu şeyler hakkında bir şey bilmiyordum görüntüleme bilim adamları için çalıştık!

renk farkı teorisi üzerine okuma Daha fazla eğlence için deneyin:

En Lab Hakkında Daha Fazla ayrıntı http://en.kioskea.net/video/cie-lab.php3 Ben şu anda aslında dönüşüm formülleri vardı olmayan bir çirkin sayfayı bulamıyor ama emin birisi bu düzenleyecek ben birini içerecek şekilde cevap.

Cevap 16/09/2008 saat 17:08
kaynak kullanıcı

oy
8

cmetric.htm Yukarıdaki bağlantı bana, hem de nasıl en iyi renk mesafeyi hesaplamak için renk mesafesi I (çok uzun jurney sonra ..) bulunan birçok diğer uygulamalar için başarısız oldu ve .. en bilimsel olarak doğru bir şekilde: DeltaE ve 2 den (!) RGB OpenCV kullanarak değerleri:

Bu JavaScriptin bazı kod dönüşümü (3 renk alanı dönüşüm gerekli http://svn.int64.org/viewvc/int64/colors/colors.js C) ++

Ve nihayet kodu (, kutudan çıktığı çalışmak hiç kimse ciddi bir hata bulduğunda umut görünüyor ... ama bir takım testler sonrasında iyi görünüyor)

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

Birini yardımcı olur umarım :)

Cevap 17/10/2013 saat 02:39
kaynak kullanıcı

oy
4

HSV renk uzayı insan renk algısı için daha iyidir. Göre Wikipedia :

insanların renkleri algılamasıyla nasıl şekillerde farklılıkların modelleri taklit çünkü böyle RGB veya CMYK gibi alternatif modellere göre HSV veya HSL renk modeli kullanmak için, sanat malzemeleri, sayısallaştırılmış resim veya diğer medya ile çalışma konusunda bazen tercih edilir. RGB ve CMYK primer renk ışıklar ya da pigmentler (sırasıyla) karıştırıldığında yeni renkler oluşturmak üzere bir araya biçimini modelleme sırasıyla katkı maddesi ve çıkartılan modellerdir.

HSV dizisinin grafiksel anlatımı

Cevap 04/08/2008 saat 16:16
kaynak kullanıcı

oy
3

Renk farklılıkları üzerinde Wikipedia makalesi renk mesafeleri insan algısı ile anlaşmak tasarlanmış renk boşluk ve mesafe ölçütlerinin bir numarası listelenir.

Cevap 24/08/2008 saat 16:38
kaynak kullanıcı

oy
2

birisi olarak ben o zaman daha uzaklaşalım, normal vizyon eklemeyi deneyin iyidir inanıyoruz renk körü kim. Renk körlüğü en yaygın biçimi kırmızı / yeşil eksikliktir. O bunu görmek daha zor ve farklılıkları görmek daha zor olduğu anlamına gelir, kırmızı ya da yeşil göremiyorum anlamına gelmez. Bir renkle önce daha büyük bir ayrılık alır Yani kör kişi farkı söyleyebilir.

Cevap 16/09/2008 saat 17:45
kaynak kullanıcı

oy
2

Eh, aramanın ilk noktası olarak, İnsanların RGB veya CYMK demek daha renk algıladıkları nasıl daha iyi temsilcisi ortak ölçütler HSV (Hue, Doygunluk ve Değer) veya HSL söyleyebil. Bkz HSL, Vikipedi'de HSV .

Ben safça İki renkler için HSL uzayda noktalar çizmek ve fark vektörü büyüklüğünü hesaplamak herhalde. Ancak bu parlak sarı ve parlak yeşil koyu yeşil yeşil kadar farklı kabul edilir anlamına gelir. Ama sonra birçok kırmızı ve pembe iki farklı renk düşünün.

Ayrıca, bu parametre alanı aynı yönde farklılık vektörleri eşit değildir. Örneğin, insan gözü diğer renkler çok daha iyi yeşil alır. kırmızı bir sapma olarak aynı miktarda yeşilden tondaki bir kayma büyük görünebilir. Ayrıca sıfıra az miktarda gelen doygunluk içinde bir kayma gri ve pembe arasındaki farktır, başka yerde vardiya kırmızı iki tonları arasındaki fark olacaktır.

görünümünde bir programcı noktadan itibaren, fark vektörleri çizmek ama HSL alanı çeşitli bölgelerde buna göre uzunlukları ayarlamak olacak bir orantı matrisi ile değiştirilmiş gerekir - bu oldukça keyfi olacağını ve çeşitli renk teorisi fikirler dayalı olacağını ancak Eğer bu uygulamak istediği bağlı oldukça keyfi olarak.

Herkes zaten online böyle bir şey yaptıysa da iyisi, görebiliyordu ...

Cevap 04/08/2008 saat 16:37
kaynak kullanıcı

oy
2

En kolay mesafe elbette sadece 3d vektörler aynı kökenli kaynaklanan ve bitiş noktaları arasındaki mesafeyi alarak renkleri dikkate almak olacaktır.

Yeşil yoğunluğunu yargılarken daha belirgin olduğunu böyle faktörleri dikkate almak gerekir, değerlerini ağırlığında olabilir.

ImageMagic aşağıdaki ölçekler sağlamaktadır:

  • kırmızı: 0.3
  • yeşil: 0.6
  • Mavi: 0.1

Tabii ki, böyle değerleri sadece similiarity sipariş olacağını için bu nedenle tüm değerleri kullanabilirsiniz, diğer renkler için değil, insanlara anlamlı olur bir şey olarak diğer değerlere ilişkin anlamlı olacaktır.

Cevap 04/08/2008 saat 16:14
kaynak kullanıcı

oy
2

spam gibi dursa da, bu bağlantı rengi alanlar için gerçekten ilginç olabilir :)

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

Cevap 04/08/2008 saat 16:14
kaynak kullanıcı

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