Lab颜色空间进行颜色提取 及其实现
这段时间在做车灯检测,晚上有些尾灯偏黄色亮度偏弱,仅用灰度度是不够的,经比较了在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;
}