RGB顏色空間轉LAB
第一:LAB顏色空間簡介
Lab是由一個亮度通道(channel)和兩個顏色通道組成的。在Lab顏色空間中,每個顏色用L、a、b三個數字表示,各個分量的含義是這樣的:
- L分量用於表示像素的亮度,取值範圍是[0,100],表示從純黑到純白
- a表示從紅色到綠色的範圍,取值範圍是[127,-128]
- b表示從黃色到藍色的範圍,取值範圍是[127,-128]
第二:爲什麼使用LAB顏色空間
因爲它是一種設備無關的顏色系統,也是一種基於生理特徵的顏色系統。它所描述的顏色空間就是人眼的視覺感應。
第三:從RGB到LAB
- 使用opencv自帶的函數,在opencv裏可以使用cvtColor函數來實現。
cvtColor(img1, img1, CV_BGR2Lab)
2.自定義函數進行轉換,因爲cvtColor函數的效率太慢,所以自己寫一個函數來將RGB顏色空間轉換爲LAB空間。
void rgbToLab(cv::Mat &img) {
double Lab_sum = 0;
double Lab_L, Lab_a, Lab_b;
double X, Y, Z;
double ref_X = 96.4221;
double ref_Y = 100.000;
double ref_Z = 82.5211;
int rowNumber = img.rows; //獲取圖像矩陣行數
int colNumber = img.cols*img.channels(); //
for (int row = 0; row < rowNumber; row++) {
uchar* pixelPtr = img.ptr<uchar>(row);
for (int col = 0; col < colNumber; col++) {
double b = pixelPtr[col] / 255.000;
double g = pixelPtr[col +1] / 255.000;
double r = pixelPtr[col +2] / 255.000;
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;
X = r * 0.436052025 + g * 0.385081593 + b * 0.143087414;
Y = r * 0.222491598 + g * 0.716886060 + b * 0.060621486;
Z = r * 0.013929122 + g * 0.097097002 + b * 0.714185470;
X = X * 100.000;
Y = Y * 100.000;
Z = Z * 100.000;
X = X / ref_X;
Y = Y / ref_Y;
Z = Z / ref_Z;
if (X > 0.008856)
X = pow(X, 1 / 3.000);
else
X = (7.787 * X) + (16 / 116.000);
if (Y > 0.008856)
Y = pow(Y, 1 / 3.000);
else
Y = (7.787 * Y) + (16 / 116.000);
if (Z > 0.008856)
Z = pow(Z, 1 / 3.000);
else
Z = (7.787 * Z) + (16 / 116.000);
Lab_L = (116.000 * Y) - 16.000;
Lab_a = 500.000 * (X - Y);
Lab_b = 200.000 * (Y - Z);
Lab_L = Lab_L * 255 / 100;
Lab_a = Lab_a + 128;
Lab_b = Lab_b + 128;
pixelPtr[col] = Lab_L;
pixelPtr[++col] = Lab_a;
pixelPtr[++col] = Lab_b;
}
}
}
因爲rgb顏色空間不能直接轉化爲lab空間,所以需要通過公式先將其轉化爲xyz顏色空間,再轉化爲lab。通過指針去遍歷圖像中的每個像素點的值,再通過公式轉換。可以達到同樣的效果,並且指針遍歷的方式效率很高。值得注意的是,opencv的一個像素的三通道值不是[0],[1],[2]對應r,g,b而是對應爲b,g,r的值。