這段時間在做車燈檢測,晚上有些尾燈偏黃色亮度偏弱,僅用灰度度是不夠的,經比較了在RGB、HSV、Lab顏色空間下進行顏色提取,發現Lab顏色模型的效果是最好的。下面介紹Lab的原理及其代碼實現。
Lab顏色模型由三個要素組成,一個要素是亮度(L),a 和b是兩個顏色通道。a包括的顏色是從深綠色(低亮度值)到灰色(中亮度值)再到亮粉紅色(高亮度值);b是從亮藍色(低亮度值)到灰色(中亮度值)再到黃色(高亮度值)。因此,這種顏色混合后將產生具有明亮效果的色彩。(這段百度的,哈哈 )
RGB轉換到Lab顏色空間,這個里http://blog.csdn.net/shamaozi/article/details/6221029 有介紹。其中,最精華的公式如下:
L = Y1 = (13933 * R + 46871 * G + 4732 * B) div 2^16
a = 377 * (14503 * R - 22218 * G + 7714 * B) div 2^24 + 128
b = 160 * (12773 * R + 39695 * G - 52468 * B) div 2^24 + 128
BGR轉換到Lab,下面顯示了L、a、b三通道的效果圖。從中可以看出提取顏色的基本方法。灰度圖沒有顏色,故在a和b通道中值為 128;(-127~127);提取不同的顏色 可以在 三個通道上選取相應的閾值。
轉換代碼如下:
#include <iostream>
#include <fstream>
#include <opencv2/opencv.hpp>
#include <stdio.h>
using namespace std;
using namespace cv;
int main()
{
Mat srcImg = imread("0.jpg");
Mat rgbImg;
if (!srcImg.data)
{
cerr<<" faild read Image"<<endl;
return -1;
}
float nScale = 1;//0.25;
Size sz;
sz.width = (int)(srcImg.cols * nScale);
sz.height = (int)(srcImg.rows * nScale);
rgbImg.create(sz, srcImg.type());
resize(srcImg,rgbImg,sz);
for (int i = 0; i < rgbImg.rows; ++i)
{
uchar* Bdata = BGR_mv[0].ptr<uchar>(i);
uchar* Gdata = BGR_mv[1].ptr<uchar>(i);
uchar* Rdata = BGR_mv[2].ptr<uchar>(i);
uchar* Ldata = LImg.ptr<uchar>(i);
uchar* adata = aImg.ptr<uchar>(i);
uchar* bdata = bImg.ptr<uchar>(i);
for (int j = 0; j < rgbImg.cols; ++j)
{
//L
Ldata[j] = (13933 * Rdata[j] + 46871*Gdata[j] + 4732*Bdata[j]) / 65536;
//a
adata[j] = 377 * (14503 * Rdata[j] - 22218*Gdata[j] + 7714*Bdata[j]) / 16777216 + 128;
//b
bdata[j] = 160 * (12773 * Rdata[j] + 39695*Gdata[j] - 52468*Bdata[j])/ 16777216 + 128;
//L
// Ldata[j] = (0.2126 * Rdata[j] + 0.7152*Gdata[j] + 0.0722*Bdata[j]);
//a
// adata[j] = 1.4749 * (0.2213 * Rdata[j] - 0.3390*Gdata[j] + 0.1177*Bdata[j]) + 128;
//b
// bdata[j] = 0.6245 * (0.1949 * Rdata[j] + 0.6057*Gdata[j] - 0.8006*Bdata[j]) + 128;
}
imshow("b",bImg);
imshow("a",aImg);
imshow("L",LImg);
waitKey(0);
return 0;
}