这里以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. 怎么用php实现短信验证码发送

    我在在众多的第三方短信服务商里选择了云片网这个短信服务商,我也会尽可能利用最简单的方式去帮助广大开发者解决短信验证码功能模块的实现. 再次之前我也参考了大部分网上的博客等,大多数都是把云片网的demo ...

  2. WPF Win32 API 嵌入Form 窗体

    WIn32 API: public class Win32Native { [DllImport("user32.dll", SetLastError = true, CharSe ...

  3. c++ STL之unordered_map

    1.1 特性 关联性:通过key去检索value,而不是通过绝对地址(和顺序容器不同) 无序性:使用hash表存储,内部无序 Map : 每个值对应一个键值 键唯一性:不存在两个元素的键一样 动态内存 ...

  4. openstack核心组件--neutron网络服务2(4)

    一.虚拟机获取 ip:   用 namspace 隔离 DHCP 服务   Neutron 通过 dnsmasq 提供 DHCP 服务,而 dnsmasq 通过 Linux Network Names ...

  5. spring-kafka —— 生产者消费者重要配置

    一.生产者配置 # 以逗号分隔的主机:端口对列表,用于建立与Kafka群集的初始连接 spring.kafka.producer.bootstrap-servers=TopKafka1:9092,To ...

  6. 三、使用VSCode配置简单的vue项目

    由于最近要使用的项目框架为前后端分离的,采用的是vue.js+webAPI的形式进行开发的.因为之前我没有接触过vue.js,也只是通过视频文档做了一些简单的练习.今天技术主管说让大家熟悉下VSCod ...

  7. django 之(一) --- DjangoRestFormwork

    接口概念 IOP:面向接口编程,不再关注具体的实现:只关注输入.输出. http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practice ...

  8. PJzhang:python基础进阶的10个疗程-one

    猫宁!!! 课程导学 北京理工大学 国家精品在线开放课程 零基础.大学水平 100行左右的python可以做很多事情 编程是基本技能,体会思维 时间成本和收益的关系 每周5个小时 https://py ...

  9. 《精通并发与Netty》学习笔记(04 - Google Protobuf介绍)

    一 .Google Protobuf 介绍 protobuf是google团队开发的用于高效存储和读取结构化数据的工具,是Google的编解码技术,在业界十分流行,通过代码生成工具可以生成不同语言版本 ...

  10. 齐治堡垒机ShtermClient-2.1.1命令执行漏洞(CNVD-2019-09593)分析

    一.基本信息 参考:https://www.cnvd.org.cn/flaw/show/1559039 补丁信息:该漏洞的修复补丁已于2019年4月1日发布.如果客户尚未修复该补丁,可联系齐治科技的技 ...