OpenCV代码提取 cvtColor函数的实现

本文介绍了OpenCV中的cvtColor函数,该函数用于在不同的颜色空间之间进行转换。文章提取并展示了cvtColor的实现代码,经过测试,与OpenCV 3.1版本的转换结果相符。
摘要由CSDN通过智能技术生成
               

 OpenCV中的cvtColor函数包括了很多颜色格式之间的转换,用起来很方便,这里对cvtColor函数的code进行了提取,经测试,和OpenCV3.1结果完全一致。

 实现代码cvtColor.hpp:

// fbc_cv is free software and uses the same licence as OpenCV// Email: fengbingchun@163.com#ifndef FBC_CV_CVTCOLOR_HPP_#define FBC_CV_CVTCOLOR_HPP_// reference: include/opencv2/imgproc.hpp#include "core/mat.hpp"#include "core/saturate.hpp"#include "imgproc.hpp"#include "core/core.hpp"namespace fbc {
   #define  FBC_DESCALE(x,n)     (((x) + (1 << ((n)-1))) >> (n))template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_RGB2RGB(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx);template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_RGB2Gray(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx);template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_Gray2RGB(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst);template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_RGB2YCrCb(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx, const float* coeffs_f, const int* coeffs_i);template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_YCrCb2RGB(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx, const float* coeffs_f, const int* coeffs_i);template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_RGB2XYZ(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx);template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_XYZ2RGB(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx);template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_RGB2HSV(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx, int hrange);template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_RGB2HLS(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx, int hrange);template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_HSV2RGB(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx, int hrange);template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_HLS2RGB(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx, int hrange);template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_RGB2Lab(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx, const float* coeffs, const float* whitept, bool srgb);template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_RGB2Luv(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx, const float* coeffs, const float* whitept, bool srgb);template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_Lab2RGB(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx, const float* coeffs, const float* whitept, bool srgb);template<typename _Tp, int chs1, int chs2> static int CvtColorLoop_Luv2RGB(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int bidx, const float* coeffs, const float* whitept, bool srgb);// Converts an image from one color space to another// support type: uchar/ushort/floattemplate<typename _Tp, int chs1, int chs2>int cvtColor(const Mat_<_Tp, chs1>& src, Mat_<_Tp, chs2>& dst, int code){ FBC_Assert(src.cols > 0 &&  src.rows > 0 && dst.cols > 0 && dst.rows > 0); FBC_Assert(src.cols == dst.cols); FBC_Assert(src.data != NULL && dst.data != NULL); FBC_Assert((sizeof(_Tp) == 1) || sizeof(_Tp) == 2 || sizeof(_Tp) == 4); // uchar || ushort || float int scn = src.channels; int dcn = dst.channels; // number of channels in the destination image Size sz = src.size(); Size dz = dst.size(); int bidx; switch (code) {  case CV_BGR2BGRA: case CV_RGB2BGRA: case CV_BGRA2BGR:  case CV_RGBA2BGR: case CV_RGB2BGR: case CV_BGRA2RGBA: {   FBC_Assert(scn == 3 || scn == 4);   dcn = code == CV_BGR2BGRA || code == CV_RGB2BGRA || code == CV_BGRA2RGBA ? 4 : 3;   FBC_Assert(dst.channels == dcn);   bidx = code == CV_BGR2BGRA || code == CV_BGRA2BGR ? 0 : 2;   CvtColorLoop_RGB2RGB(src, dst, bidx); // uchar/ushort/float   break;  }  case CV_BGR2GRAY: case CV_BGRA2GRAY: case CV_RGB2GRAY: case CV_RGBA2GRAY: {   FBC_Assert(scn == 3 || scn == 4);   FBC_Assert(dst.channels == 1);   bidx = code == CV_BGR2GRAY || code == CV_BGRA2GRAY ? 0 : 2;   CvtColorLoop_RGB2Gray(src, dst, bidx);   break;  }  case CV_GRAY2BGR: case CV_GRAY2BGRA: {   FBC_Assert(scn == 1 && (dcn == 3 || dcn == 4));   CvtColorLoop_Gray2RGB(src, dst);   break;  }  case CV_BGR2YCrCb: case CV_RGB2YCrCb:  case CV_BGR2YUV: case CV_RGB2YUV: {   FBC_Assert(scn == 3 || scn == 4);   bidx = code == CV_BGR2YCrCb || code == CV_BGR2YUV ? 0 : 2;   static const float yuv_f[] = { 0.114f, 0.587f, 0.299f, 0.492f, 0.877f };   static const int yuv_i[] = { B2Y, G2Y, R2Y, 8061, 14369 };   const float* coeffs_f = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_f;   const int* coeffs_i = code == CV_BGR2YCrCb || code == CV_RGB2YCrCb ? 0 : yuv_i;   CvtColorLoop_RGB2YCrCb(src, dst, bidx, coeffs_f, coeffs_i);   break;  }  case CV_YCrCb2BGR: case CV_YCrCb2RGB:  case CV_YUV2BGR: case CV_YUV2RGB: {   FBC_Assert(scn == 3 && (dcn == 3 || dcn == 4));   bidx = code == CV_YCrCb2BGR || code == CV_YUV2BGR ? 0 : 2;   static const float yuv_f[] = { 2.032f, -0.395f, -0.581f, 1.140f };   static const int yuv_i[] = { 33292, -6472, -9519, 18678 };   const float* coeffs_f = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_f;   const int* coeffs_i = code == CV_YCrCb2BGR || code == CV_YCrCb2RGB ? 0 : yuv_i;   CvtColorLoop_YCrCb2RGB(src, dst, bidx, coeffs_f, coeffs_i);   break;  }  case CV_BGR2XYZ: case CV_RGB2XYZ: {   FBC_Assert(scn == 3 || scn == 4);   bidx = code == CV_BGR2XYZ ? 0 : 2;   CvtColorLoop_RGB2XYZ(src, dst, bidx);   break;  }  case CV_XYZ2BGR: case CV_XYZ2RGB: {   FBC_Assert(scn == 3 && (dcn == 3 || dcn == 4));   bidx = code == CV_XYZ2BGR ? 0 : 2;   CvtColorLoop_XYZ2RGB(src, dst, bidx);   break;  }  case CV_BGR2HSV: case CV_RGB2HSV: case CV_BGR2HSV_FULL: case CV_RGB2HSV_FULL:  case CV_BGR2HLS: case CV_RGB2HLS: case CV_BGR2HLS_FULL: case CV_RGB2HLS_FULL: {   FBC_Assert(scn == 3 || scn == 4);   FBC_Assert(sizeof(_Tp) == 1 || sizeof(_Tp) == 4);   bidx = code == CV_BGR2HSV || code == CV_BGR2HLS ||    code == CV_BGR2HSV_FULL || code == CV_BGR2HLS_FULL ? 0 : 2;   int hrange = sizeof(_Tp) == 4 ? 360 : code == CV_BGR2HSV || code == CV_RGB2HSV ||    code == CV_BGR2HLS || code == CV_RGB2HLS ? 180 : 256;   if (code == CV_BGR2HSV || code == CV_RGB2HSV || code == CV_BGR2HSV_FULL || code == CV_RGB2HSV_FULL) {    CvtColorLoop_RGB2HSV(src, dst, bidx, hrange);   } else {    CvtColorLoop_RGB2HLS(src, dst, bidx, hrange);   }   break;  }  case CV_HSV2BGR: case CV_HSV2RGB: case CV_HSV2BGR_FULL: case CV_HSV2RGB_FULL:  case CV_H
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值