Lab颜色空间进行颜色提取 及其实现 - 计算机视觉&机器视觉

时间:2024-03-06 10:51:09

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