首页 > 代码库 > OpenCV源码分析:RGB到其他色彩空间的转换

OpenCV源码分析:RGB到其他色彩空间的转换

1.流程调用图

 

2.部分代码分析

//模板函数进行颜色空间的转换

template <typename Cvt>

void CvtColorLoop(const Mat& src, Mat& dst, const Cvt& cvt)

{

  //封装Tbb的并行结构parallel_forOpenCV导出为:parallel_for_

  //Range:迭代范围类 CvtColorLoop_Invoker<Cvt>:模板类

  parallel_for_(Range(0, src.rows), CvtColorLoop_Invoker<Cvt>(src, dst, cvt), 

src.total()/(double)(1<<16) );

}

 

//OpenCV导出迭代范围类:Range

class CV_EXPORTS Range

{

public:

  Range();

  Range(int _start, int _end);

  Range(const CvSlice& slice);

  int size() const;

  bool empty() const;

  static Range all();

  operator CvSlice() const;

  int start, end;

};

//模板类继承纯虚基类ParallelLoopBody

template <typename Cvt>

class CvtColorLoop_Invoker : public ParallelLoopBody

{

//模板类的类型

  typedef typename Cvt::channel_type _Tp;

public:

 

//模板类的构造函数变量传递,传入数据

CvtColorLoop_Invoker(const Mat& _src, Mat& _dst, const Cvt& _cvt) :

ParallelLoopBody(), src(_src), dst(_dst), cvt(_cvt){}

 

//子类化纯虚函数,遍历Mat的行数

virtual void operator()(const Range& range) const

{

  const uchar* yS = src.ptr<uchar>(range.start);

  uchar* yD = dst.ptr<uchar>(range.start);

 

  for( int i = range.start; i < range.end; ++i, yS += src.step, yD += dst.step )

   cvt((const _Tp*)yS, (_Tp*)yD, src.cols);

}

 

private:

  const Mat& src;

  Mat& dst;

  const Cvt& cvt;

  const CvtColorLoop_Invoker& operator= (const CvtColorLoop_Invoker&);

};

 

//模板类的具体实现

struct RGB2HLS_S_f

{

//明确具体的数据类型:float

typedef float channel_type;

 

//传入其他相关参数

RGB2HLS_S_f(int _srccn, int _blueIdx): srccn(_srccn), blueIdx(_blueIdx) {}

//在模板类中被调用,遍历Mat的列数,并进行具体的取值及其他运算:核心公式计算部分

void operator()(const float* src, float* dst, int n) const

{     int i, bidx = blueIdx, scn = srccn;

      n *= 3;

      for( i = 0; i < n; i += 3, src += scn )

     {

          float b = src[bidx], g = src[1], r = src[bidx^2];

          float h = 0.f, s = 0.f, l;

          float vmin, vmax, diff;

 

          vmax = vmin = r;

     if( vmax < g ) vmax = g;

     if( vmax < b ) vmax = b;

     if( vmin > g ) vmin = g;

     if( vmin > b ) vmin = b;

 

     diff = vmax - vmin;

     l = (vmax + vmin)*0.5f;

 

    if( diff > FLT_EPSILON )

    {

      s = l < 0.5f ? diff/(vmax + vmin) : diff/(2 - vmax - vmin);

    }

 

    dst[i+2] = s;

    }

   }

 

  int srccn, blueIdx;

};

 

 

OpenCV源码分析:RGB到其他色彩空间的转换