这里以CV_BGR2YUV_I420来讲

1. opencv244

core.cpp

void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
{
...
case COLOR_RGB2YUV_YV12: case COLOR_BGR2YUV_YV12: case COLOR_RGBA2YUV_YV12: case COLOR_BGRA2YUV_YV12:
case COLOR_RGB2YUV_IYUV: case COLOR_BGR2YUV_IYUV: case COLOR_RGBA2YUV_IYUV: case COLOR_BGRA2YUV_IYUV:
if (dcn <= ) dcn = ;
uidx = (code == COLOR_BGR2YUV_IYUV || code == COLOR_BGRA2YUV_IYUV || code == COLOR_RGB2YUV_IYUV || code == COLOR_RGBA2YUV_IYUV) ? : ;
CV_Assert( (scn == || scn == ) && depth == CV_8U );
CV_Assert( dcn == );
CV_Assert( sz.width % == && sz.height % == );
_dst.create(Size(sz.width, sz.height / * ), CV_MAKETYPE(depth, dcn));
dst = _dst.getMat();
hal::cvtBGRtoThreePlaneYUV(src.data, src.step, dst.data, dst.step, src.cols, src.rows,
scn, swapBlue(code), uidx);
break; ...
}

  

color.cpp

void cvtBGRtoThreePlaneYUV(const uchar * src_data, size_t src_step,
uchar * dst_data, size_t dst_step,
int width, int height,
int scn, bool swapBlue, int uIdx)
{
CV_INSTRUMENT_REGION() CALL_HAL(cvtBGRtoThreePlaneYUV, cv_hal_cvtBGRtoThreePlaneYUV, src_data, src_step, dst_data, dst_step, width, height, scn, swapBlue, uIdx);
uchar * uv_data = dst_data + dst_step * height;
RGB888toYUV420pInvoker(src_data, src_step, dst_data, uv_data, dst_step, width, height, scn, swapBlue, uIdx == , false).convert();
}   

color.cpp

struct RGB888toYUV420pInvoker: public ParallelLoopBody
{
RGB888toYUV420pInvoker(const uchar * _src_data, size_t _src_step,
uchar * _y_data, uchar * _uv_data, size_t _dst_step,
int _src_width, int _src_height, int _scn, bool swapBlue_, bool swapUV_, bool interleaved_)
: src_data(_src_data), src_step(_src_step),
y_data(_y_data), uv_data(_uv_data), dst_step(_dst_step),
src_width(_src_width), src_height(_src_height),
scn(_scn), swapBlue(swapBlue_), swapUV(swapUV_), interleaved(interleaved_) { } void operator()(const Range& rowRange) const
{
const int w = src_width;
const int h = src_height;
const int cn = scn;
for( int i = rowRange.start; i < rowRange.end; i++ )
{
const uchar* brow0 = src_data + src_step * ( * i);
const uchar* grow0 = brow0 + ;
const uchar* rrow0 = brow0 + ;
const uchar* brow1 = src_data + src_step * ( * i + );
const uchar* grow1 = brow1 + ;
const uchar* rrow1 = brow1 + ;
if (swapBlue)
{
std::swap(brow0, rrow0);
std::swap(brow1, rrow1);
} uchar* y = y_data + dst_step * (*i);
uchar* u;
uchar* v;
if (interleaved)
{
u = uv_data + dst_step * i;
v = uv_data + dst_step * i + ;
}
else
{
u = uv_data + dst_step * (i/) + (i % ) * (w/);
v = uv_data + dst_step * ((i + h/)/) + ((i + h/) % ) * (w/);
} if (swapUV)
{
std::swap(u, v);
} for( int j = , k = ; j < w * cn; j += * cn, k++ )
{
int r00 = rrow0[j]; int g00 = grow0[j]; int b00 = brow0[j];
int r01 = rrow0[cn + j]; int g01 = grow0[cn + j]; int b01 = brow0[cn + j];
int r10 = rrow1[j]; int g10 = grow1[j]; int b10 = brow1[j];
int r11 = rrow1[cn + j]; int g11 = grow1[cn + j]; int b11 = brow1[cn + j]; const int shifted16 = ( << ITUR_BT_601_SHIFT);
const int halfShift = ( << (ITUR_BT_601_SHIFT - ));
int y00 = ITUR_BT_601_CRY * r00 + ITUR_BT_601_CGY * g00 + ITUR_BT_601_CBY * b00 + halfShift + shifted16;
int y01 = ITUR_BT_601_CRY * r01 + ITUR_BT_601_CGY * g01 + ITUR_BT_601_CBY * b01 + halfShift + shifted16;
int y10 = ITUR_BT_601_CRY * r10 + ITUR_BT_601_CGY * g10 + ITUR_BT_601_CBY * b10 + halfShift + shifted16;
int y11 = ITUR_BT_601_CRY * r11 + ITUR_BT_601_CGY * g11 + ITUR_BT_601_CBY * b11 + halfShift + shifted16; y[*k + ] = saturate_cast<uchar>(y00 >> ITUR_BT_601_SHIFT);
y[*k + ] = saturate_cast<uchar>(y01 >> ITUR_BT_601_SHIFT);
y[*k + dst_step + ] = saturate_cast<uchar>(y10 >> ITUR_BT_601_SHIFT);
y[*k + dst_step + ] = saturate_cast<uchar>(y11 >> ITUR_BT_601_SHIFT); const int shifted128 = ( << ITUR_BT_601_SHIFT);
int u00 = ITUR_BT_601_CRU * r00 + ITUR_BT_601_CGU * g00 + ITUR_BT_601_CBU * b00 + halfShift + shifted128;
int v00 = ITUR_BT_601_CBU * r00 + ITUR_BT_601_CGV * g00 + ITUR_BT_601_CBV * b00 + halfShift + shifted128; if (interleaved)
{
u[k*] = saturate_cast<uchar>(u00 >> ITUR_BT_601_SHIFT);
v[k*] = saturate_cast<uchar>(v00 >> ITUR_BT_601_SHIFT);
}
else
{
u[k] = saturate_cast<uchar>(u00 >> ITUR_BT_601_SHIFT);
v[k] = saturate_cast<uchar>(v00 >> ITUR_BT_601_SHIFT);
}
}
}
} void convert() const
{
if( src_width * src_height >= * )
parallel_for_(Range(, src_height/), *this);
else
operator()(Range(, src_height/));
} private:
RGB888toYUV420pInvoker& operator=(const RGB888toYUV420pInvoker&); const uchar * src_data;
size_t src_step;
uchar *y_data, *uv_data;
size_t dst_step;
int src_width;
int src_height;
const int scn;
bool swapBlue;
bool swapUV;
bool interleaved;
};   

2.   opencv347   使用opencl

bool oclCvtColorTwoPlaneYUV2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx, int uidx )
{
OclHelper< Set<>, Set<, >, Set<CV_8U>, FROM_YUV > h(_src, _dst, dcn); if(!h.createKernel("YUV2RGB_NVx", ocl::imgproc::color_yuv_oclsrc,
format("-D dcn=%d -D bidx=%d -D uidx=%d", dcn, bidx, uidx)))
{
return false;
} return h.run();
}

【opencv源码解析】 二、 cvtColor的更多相关文章

  1. Mybatis源码解析(二) —— 加载 Configuration

    Mybatis源码解析(二) -- 加载 Configuration    正如上文所看到的 Configuration 对象保存了所有Mybatis的配置信息,也就是说mybatis-config. ...

  2. RxJava2源码解析(二)

    title: RxJava2源码解析(二) categories: 源码解析 tags: 源码解析 rxJava2 前言 本篇主要解析RxJava的线程切换的原理实现 subscribeOn 首先, ...

  3. Sentinel源码解析二(Slot总览)

    写在前面 本文继续来分析Sentinel的源码,上篇文章对Sentinel的调用过程做了深入分析,主要涉及到了两个概念:插槽链和Node节点.那么接下来我们就根据插槽链的调用关系来依次分析每个插槽(s ...

  4. OpenCV源码解析

    OpenCV K-means源码解析 OpenCV 图片读取源码解析 OpenCV 视频播放源码解析 OpenCV 追踪算法源码解析 OpenCV SIFT算法源码解析 OpenCV 滤波源码分析:b ...

  5. iOS即时通讯之CocoaAsyncSocket源码解析二

    原文 前言 本文承接上文:iOS即时通讯之CocoaAsyncSocket源码解析一 上文我们提到了GCDAsyncSocket的初始化,以及最终connect之前的准备工作,包括一些错误检查:本机地 ...

  6. jQuery 源码解析二:jQuery.fn.extend=jQuery.extend 方法探究

    终于动笔开始 jQuery 源码解析第二篇,写文章还真是有难度,要把自已懂的表述清楚,要让别人听懂真的不是一见易事. 在 jQuery 源码解析一:jQuery 类库整体架构设计解析 一文,大致描述了 ...

  7. Common.Logging源码解析二

    Common.Logging源码解析一分析了LogManager主入口的整个逻辑,其中第二步生成日志实例工厂类接口分析的很模糊,本随笔将会详细讲解整个日志实例工厂类接口的生成过程! (1).关于如何生 ...

  8. erlang下lists模块sort(排序)方法源码解析(二)

    上接erlang下lists模块sort(排序)方法源码解析(一),到目前为止,list列表已经被分割成N个列表,而且每个列表的元素是有序的(从大到小) 下面我们重点来看看mergel和rmergel ...

  9. element-ui 源码解析 二

    Carousel 走马灯源码解析 1. 基本原理:页面切换 页面切换使用的是 transform 2D 转换和 transition 过渡 可以看出是采用内联样式来实现的 举个栗子 <div : ...

  10. ArrayList源码解析(二)

    欢迎转载,转载烦请注明出处,谢谢. https://www.cnblogs.com/sx-wuyj/p/11177257.html 自己学习ArrayList源码的一些心得记录. 继续上一篇,Arra ...

随机推荐

  1. Oracle CDC (Change Data Capture)更新数据捕获——Asynchronous HotLog Mode(附带简单的kettle任务实现数据同步)

    Performing Asynchronous HotLog Publishing Step 1   Source Database DBA: Set the database initializat ...

  2. 一百:CMS系统之修改密码逻辑

    定义一个基类form,用于获取错误信息 from wtforms import Form class BaseForm(Form): def get_error(self): # a = {'aaa' ...

  3. iscsi序列一、搭建iscsi存储系统

    一.NAS和SAN服务器概述 SAS: 容量小, 300G, 600G, 900G, 价格贵. SATA:容量大,500G, 750G, 1T, 2T, 3T, 4T   不支持热插拔,价格低. 假S ...

  4. Vue组件v-if新渲染的组件不更新

    Vue组件v-if新渲染的组件不更新:可能原因是Vue识别到是相似组件(高度相似甚至相同)不会更新元素.给原来的组件和新组件分别给不同的key值让Vue识别为不同的组件.

  5. redis开启持久化、redis 数据备份与恢复

    redis持久化介绍  https://segmentfault.com/a/1190000015897415 1. 开启aof持久化.以守护进程启动.远程访问先把配置文件拷贝一份到/etc/redi ...

  6. springboot和jsp,以及引入jquery

    包: src: main: java: resources: static: templates: test: 2.在static导入jquery源文件,在templates写入jsp文件 3.配置文 ...

  7. 文件上传and富文本页面

    文件上传功能: 1.首先在index.jsp的界面上初始化一个表单. <body> <form enctype="multipart/form-data" act ...

  8. 【CodeForces - 598D】Igor In the Museum(bfs)

    Igor In the Museum Descriptions 给你一个n*m的方格图表示一个博物馆的分布图.每个方格上用'*'表示墙,用'.'表示空位.每一个空格和相邻的墙之间都有一幅画.(相邻指的 ...

  9. freeRTOS学习8-20

  10. Java中对JSONArray中的对象进行排序

    String jsonArrStr = "[ { \"ID\": \"135\", \"Name\": \"Fargo ...