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

1.流程调用图

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

2.部分代码分析

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

template <typename Cvt>

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

{

//封装Tbb的并行结构parallel_for,OpenCV导出为: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;

};

上一篇:freemaker获取字符串长度


下一篇:Nginx日常维护操作(3)