1.流程调用图
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;
};