2017-10-22 3 views
-2

イメージのRGBカラーをLAB空間に変換するこの関数を使用しています。C++を使用したLAB変換

void RGB2LAB(
    const vector<uint> &    ubuff, 
    vector<double>&     lvec, 
    vector<double>&     avec, 
    vector<double>&     bvec) 
{ 
    int sz = int(ubuff.size()); 

    lvec.resize(sz); 
    avec.resize(sz); 
    bvec.resize(sz); 

    for(int j = 0; j < sz; j++) 
    { 
     int sR = (ubuff[j]>> 16) & 0xFF; //<---- 
     int sG = (ubuff[j] >> 8) & 0xFF; //<---- 
     int sB = (ubuff[j] ) & 0xFF;  //<---- 
     //------------------------ 
     // sRGB to XYZ conversion 
     // (D65 illuminant assumption) 
     //------------------------ 
     double R = sR/255.0; 
     double G = sG/255.0; 
     double B = sB/255.0; 

     double r, g, b; 

     if(R <= 0.04045) r = R/12.92; 
     else    r = pow((R+0.055)/1.055,2.4); 
     if(G <= 0.04045) g = G/12.92; 
     else    g = pow((G+0.055)/1.055,2.4); 
     if(B <= 0.04045) b = B/12.92; 
     else    b = pow((B+0.055)/1.055,2.4); 

     double X = r*0.4124564 + g*0.3575761 + b*0.1804375; 
     double Y = r*0.2126729 + g*0.7151522 + b*0.0721750; 
     double Z = r*0.0193339 + g*0.1191920 + b*0.9503041; 
     //------------------------ 
     // XYZ to LAB conversion 
     //------------------------ 
     double epsilon = 0.008856; //actual CIE standard 
     double kappa = 903.3;  //actual CIE standard 

     double Xr = 0.950456; //reference white 
     double Yr = 1.0;  //reference white 
     double Zr = 1.088754; //reference white 

     double xr = X/Xr; 
     double yr = Y/Yr; 
     double zr = Z/Zr; 

     double fx, fy, fz; 
     if(xr > epsilon) fx = pow(xr, 1.0/3.0); 
     else    fx = (kappa*xr + 16.0)/116.0; 
     if(yr > epsilon) fy = pow(yr, 1.0/3.0); 
     else    fy = (kappa*yr + 16.0)/116.0; 
     if(zr > epsilon) fz = pow(zr, 1.0/3.0); 
     else    fz = (kappa*zr + 16.0)/116.0; 

     lvec[j] = 116.0*fy-16.0; 
     avec[j] = 500.0*(fx-fy); 
     bvec[j] = 200.0*(fy-fz); 
    } 




} 

本当の意味と、これらのシンボルの利益は何ですか:彼らは、特定の記号(>>)と16進数を使用するので、私はライン13、14および15を理解していませんか?彼らは変換のために必須ですか?

+0

1 - >>(ここでは32ビット値のうち8つの特定のビットを抽出するために使用される)右シフトを意味します。 2 - はい、彼らはさらに非常に重要です。 – fvu

+0

C++のリファレンスガイドで '>>'をカバーしていない場合は、新しいリファレンスを入手してください。これはかなり基本的なもので、C++を直感的に習得することはできません。ガイドが必要です。少なくとも、言語のより戦略的な側面を説明するのに役立つように、[言語デザイナーによるC++の書籍](http://www.stroustrup.com/4th.html)と他のものを用意する必要があります。 C++は非常に許しがたいものですので、正しく使用する方法を読んでいない限り、プログラムがクラッシュしたり、誤動作した場合、あなたの人生は完全に悲惨になります。 – tadman

+0

これらの演算子は、言語の中心にあります。あなたが最初に言語を話さなければ、コードの意味について尋ねるのは実際には役に立たない。だから、良いC + +の本/イントロを取得し、それを介して動作します。 –

答えて

1

のは、それを打破してみましょう:

ubuffuint -sのベクトルです。各uintは32ビット(この説明では64である可能性がありますが重要ではありません)または4バイトで構成されています。

です。 ubuff[j]は、メモリ内に次のようになります。

|-- Byte1 --|-- Byte2 --|-- Byte3 --|-- Byte4 --| 

今、私たちは私たちの邪魔にならないことを持っていること、のは、オペレータ>>について話しましょう。これはシフト右演算子です。これはメモリのビットを右に回転させるものです。たとえば、次のようになります。

ubuff[j] >> 8 // ==> |-- ByteX --|-- Byte1 --|-- Byte2 --|-- Byte3 --| 

すべてのビットが8つの位置(正確には1バイト)だけどのように移動するかに注意してください。左の新しいバイトは、元の最上位ビット(左端ビット)に従って0または1を使用して埋められます。

次に、&オペレータについて説明します。ビットごとにビット単位のAND演算を実行します。たとえば:だから

(ubuff[j] >> 8) & 0xFF // ==> |-- ByteX --|-- Byte1 --|-- Byte2 --|-- Byte3 --| 
         // AND |-- 0x00 --|-- 0x00 --|-- 0x00 --|-- 0xFF --| 
         // RES |-- 0x00 --|-- 0x00 --|-- 0x00 --|-- Byte3 --| 

、我々は実際には、元のubuff[j]からByte3が残っています。

同じことが他の式に行く:

int sR = (ubuff[j] >> 16) & 0xFF; // ==> Byte2 
int sG = (ubuff[j] >> 8) & 0xFF; // ==> Byte3 
int sB = (ubuff[j]  ) & 0xFF; // ==> Byte4 
+0

ありがとうございます。 C++のこの部分を学ぶ機会はありませんでした。今私はもっと深くそれを傾けるでしょう。しかし、各ピクセルの画像の色を保存するために2Dベクトル(ベクトル ubuff(nbr_pixels、ベクトル(3,0))を使用することができますか?あなたの説明の最後の部分、Byte1は使われていませんか?) –

+0

@James_keni、標準的なコンテナを使うことができます!このメソッドは、1)非常にコンパクトで2)非常に高速です3) 4)データをシリアライズおよびデシリアライズするためのメソッドが1つだけ必要なので、一度それを書いて、必要なだけ使用します。そして、あなたはあなたの2番目の前提について正しいです。我々はR、G、B値しか持たないので、Byte1は使用されていないようです。 –

関連する問題