libyuv库的使用
libyuv是Google开源的实现各种YUV与RGB之间相互转换、旋转、缩放的库。它是跨平台的,可在Windows、Linux、Mac、Android等操作系统,x86、x64、arm架构上进行编译运行,支持SSE、AVX、NEON等SIMD指令加速。
下面说一下libyuv在Windows7VS2013 x64上的编译步骤及使用:
1. 从https://code.google.com/p/libyuv/source/checkout或者https://github.com/lemenkov/libyuv下载libyuv源码;我是通过svn直接从google下载的,版本号是1433,更新日期2015年6月13日;
2. 通过cmake gui生成vs2013 x64工程,不需要额外的配置;
3. 打开Project.sln工程,重新编译,即可生成yuv.lib静态库;
4. 新添加一个test_libyuv控制台工程,用于测试yuv.lib的正确性,测试代码如下:
#include <iostream>
#include <assert.h>
#include "libyuv.h"
#include <cmath>
#include <opencv2/opencv.hpp>void test_BGRAToI420(const cv::Mat& matSrc, int width, int height, int size_frame, cv::Mat& matDst);
void test_BGRAToNV21(const cv::Mat& matSrc, int width, int height, int size_frame, cv::Mat& matDst);
void test_BGRAToNV12(const cv::Mat& matSrc, int width, int height, int size_frame, cv::Mat& matDst);int main(int argc, char* argv[])
{cv::Mat matSrc = cv::imread("cat.jpg");if (!matSrc.data) {std::cout << "read src image error" << std::endl;return -1;}//cv::resize(matSrc, matSrc, cv::Size(500, 111));int width = matSrc.cols;int height = matSrc.rows;int size_frame = width * height;cv::Mat matI420, matNV21, matNV12;test_BGRAToI420(matSrc, width, height, size_frame, matI420);test_BGRAToNV21(matSrc, width, height, size_frame, matNV21);test_BGRAToNV12(matSrc, width, height, size_frame, matNV12);assert((matI420.depth() == matNV21.depth()) && (matI420.depth() == matNV12.depth()));assert((matI420.channels() == matNV21.channels()) && (matI420.channels() == matNV12.channels()));for (int i = 0; i < height; i++) {const unsigned char* pI420 = matI420.ptr(i);const unsigned char* pNV21 = matNV21.ptr(i);const unsigned char* pNV12 = matNV12.ptr(i);for (int j = 0, m = 0; j < width; j++, m+=4) {if ((pI420[m] != pNV21[m]) || (pI420[m] != pNV12[m]) ||(pI420[m + 1] != pNV21[m + 1]) || (pI420[m + 1] != pNV12[m + 1]) ||(pI420[m + 2] != pNV21[m + 2]) || (pI420[m + 2] != pNV12[m + 2]) ||(pI420[m + 3] != pNV21[m + 3]) || (pI420[m + 3] != pNV12[m + 3])) {std::cout << "convert error" << std::endl;}}}std::cout << "ok" << std::endl;return 0;
}void test_BGRAToI420(const cv::Mat& matSrc, int width, int height, int size_frame, cv::Mat& matDst)
{// BGRA <--> I420(YUV420P)cv::Mat matBGRA, matI420, matARGB;cv::cvtColor(matSrc, matBGRA, cv::COLOR_BGR2BGRA);matARGB = cv::Mat(height, width, CV_8UC4, cv::Scalar::all(0));libyuv::BGRAToARGB(matBGRA.data, width * 4, matARGB.data, width * 4, width, height);uchar* pI420 = new uchar[width * height + (width + 1) / 2 * (height + 1) / 2 * 2];memset(pI420, 0, sizeof(uchar) * (width * height + (width + 1) / 2 * (height + 1) / 2 * 2));uchar* dst_y = pI420;int dst_y_stride = width;uchar* dst_u = pI420 + size_frame;int dst_u_stride = (width + 1) / 2;uchar* dst_v = pI420 + size_frame + dst_u_stride * (height + 1) / 2;int dst_v_stride = (width + 1) / 2;libyuv::BGRAToI420(matARGB.data, width * 4, dst_y, dst_y_stride, dst_u, dst_u_stride, dst_v, dst_v_stride, width, height);matI420 = cv::Mat(height, width, CV_8UC4, cv::Scalar::all(0));libyuv::I420ToBGRA(dst_y, dst_y_stride, dst_u, dst_u_stride, dst_v, dst_v_stride, matI420.data, width * 4, width, height);cv::Mat matBGRA_ = cv::Mat(height, width, CV_8UC4, cv::Scalar::all(0));libyuv::ARGBToBGRA(matI420.data, width * 4, matBGRA_.data, width * 4, width, height);cv::imwrite("I420_bgra.jpg", matBGRA_);matBGRA_.copyTo(matDst);int count_diff = 0;int max_diff = 0;int threshold = 20;//for (int i = 0; i < height; i++) {uchar* pSrc = matBGRA.ptr(i);uchar* pDst = matBGRA_.ptr(i);for (int j = 0, m = 0; j < width; j++, m += 4) {int tmp = std::max(abs(pSrc[m] - pDst[m]), abs(pSrc[m + 1] - pDst[m + 1]));tmp = std::max(tmp, abs(pSrc[m + 2] - pDst[m + 2]));if (tmp > max_diff)max_diff = tmp;if (abs(pSrc[m] - pDst[m]) > threshold ||abs(pSrc[m + 1] - pDst[m + 1]) > threshold ||abs(pSrc[m + 2] - pDst[m + 2]) > threshold) {count_diff++;//std::cout << i << " " << j << std::endl;}}}std::cout << "convert I420 to BGRA diff max: " << max_diff << std::endl;if (count_diff > width + height) {//std::cout << "convert I420 to BGRA error." << std::endl;std::cout << "diff num: " << count_diff << std::endl;}delete[] pI420;
}void test_BGRAToNV12(const cv::Mat& matSrc, int width, int height, int size_frame, cv::Mat& matDst)
{// BGRA <--> NV12cv::Mat matBGRA, matNV12;cv::cvtColor(matSrc, matBGRA, cv::COLOR_BGR2BGRA);uchar* pNV12 = new uchar[width * height + ((width + 1) / 2) * ((height + 1) / 2) * 2];memset(pNV12, 0, sizeof(uchar) * (width * height + ((width + 1) / 2) * ((height + 1) / 2) * 2));uchar* dst_y = pNV12;int dst_y_stride = width;uchar* dst_vu = pNV12 + size_frame;int dst_vu_stride = (width + 1) / 2 * 2;libyuv::ARGBToNV12(matBGRA.data, width * 4, dst_y, dst_y_stride, dst_vu, dst_vu_stride, width, height);matNV12 = cv::Mat(height, width, CV_8UC4, cv::Scalar::all(0));libyuv::NV12ToARGB(dst_y, dst_y_stride, dst_vu, dst_vu_stride, matNV12.data, width * 4, width, height);cv::imwrite("NV12_bgra.jpg", matNV12);matNV12.copyTo(matDst);int count_diff = 0;int max_diff = 0;int threshold = 20;//for (int i = 0; i < height; i++) {uchar* pSrc = matBGRA.ptr(i);uchar* pDst = matNV12.ptr(i);for (int j = 0, m = 0; j < width; j++, m += 4) {int tmp = std::max(abs(pSrc[m] - pDst[m]), abs(pSrc[m + 1] - pDst[m + 1]));tmp = std::max(tmp, abs(pSrc[m + 2] - pDst[m + 2]));if (tmp > max_diff)max_diff = tmp;if (abs(pSrc[m] - pDst[m]) > threshold ||abs(pSrc[m + 1] - pDst[m + 1]) > threshold ||abs(pSrc[m + 2] - pDst[m + 2]) > threshold) {count_diff++;//std::cout << i << " " << j << std::endl;}}}std::cout << "convert NV12 to BGRA diff max: " << max_diff << std::endl;if (count_diff > width + height) {//std::cout << "convert NV12 to BGRA error." << std::endl;std::cout << "diff num: " << count_diff << std::endl;}delete[] pNV12;
}void test_BGRAToNV21(const cv::Mat& matSrc, int width, int height, int size_frame, cv::Mat& matDst)
{// BGRA <--> NV21cv::Mat matBGRA, matNV21;cv::cvtColor(matSrc, matBGRA, cv::COLOR_BGR2BGRA);uchar* pNV21 = new uchar[width * height + ((width + 1) / 2) * ((height + 1) / 2) * 2];memset(pNV21, 0, sizeof(uchar) * (width * height + ((width + 1) / 2) * ((height + 1) / 2) * 2));uchar* dst_y = pNV21;int dst_y_stride = width;uchar* dst_vu = pNV21 + size_frame;int dst_vu_stride = (width + 1) / 2 * 2;libyuv::ARGBToNV21(matBGRA.data, width * 4, dst_y, dst_y_stride, dst_vu, dst_vu_stride, width, height);matNV21 = cv::Mat(height, width, CV_8UC4, cv::Scalar::all(0));libyuv::NV21ToARGB(dst_y, dst_y_stride, dst_vu, dst_vu_stride, matNV21.data, width * 4, width, height);cv::imwrite("NV21_bgra.jpg", matNV21);matNV21.copyTo(matDst);int count_diff = 0;int max_diff = 0;int threshold = 20;//for (int i = 0; i < height; i++) {uchar* pSrc = matBGRA.ptr(i);uchar* pDst = matNV21.ptr(i);for (int j = 0, m = 0; j < width; j++, m += 4) {int tmp = std::max(abs(pSrc[m] - pDst[m]), abs(pSrc[m + 1] - pDst[m + 1]));tmp = std::max(tmp, abs(pSrc[m + 2] - pDst[m + 2]));if (tmp > max_diff)max_diff = tmp;if (abs(pSrc[m] - pDst[m]) > threshold ||abs(pSrc[m + 1] - pDst[m + 1]) > threshold ||abs(pSrc[m + 2] - pDst[m + 2]) > threshold) {count_diff++;//std::cout << i << " " << j << std::endl;}}}std::cout << "convert NV21 to BGRA diff max: " << max_diff << std::endl;if (count_diff > width + height) {//std::cout << "convert NV21 to BGRA error." << std::endl;std::cout << "diff num: " << count_diff << std::endl;}delete[] pNV21;
}
GitHub: https://github.com/fengbingchun/Libyuv_Test
相关文章:

封装 vue 组件的过程记录
在我们使用vue的开发过程中总会遇到这样的场景,封装自己的业务组件。 封装页面组件前要考虑几个问题:1、该业务组件的使用场景 2、在什么条件下展示一些什么数据,数据类型是什么样的,及长度颜色等 3、如果是通用的内容,…
Service的基本组成
Service与Activity的最大区别就是一有界面,一个没有界面。 如果某些程序操作很消耗时间,那么可以将这些程序定义在Service之中,这样就可以完成程序的后台运行, 其实Service就是一个没有界面的Activity,执行跨进程访问也…
BP神经网络公式推导及实现(MNIST)
BP神经网络的基础介绍见:http://blog.csdn.net/fengbingchun/article/details/50274471,这里主要以公式推导为主。BP神经网络又称为误差反向传播网络,其结构如下图。这种网络实质是一种前向无反馈网络,具有结构清晰、易实现、计算…
AI应用落地哪家强?CSDN AI Top 30+案例评选等你来秀!
人工智能历经百年发展,如今迎来发展的黄金时期。目前,AI 技术已涵盖自然语言处理、模式识别、图像识别、数据挖掘、机器学习等领域的研究,在汽车、金融、教育、医疗、安防、零售、家居、文娱、工业等行业获得了令人印象深刻的成果。 在各行业…
安利Mastodon:属于未来的社交网络
我为Mastodon开发了一款安卓客户端,v1.0版本已经发布,欢迎下载使用 源码在这里:https://github.com/shuiRong/Gakki ??? 正文 Mastodon(长毛象)是什么? 是一个免费开源、去中心化、分布式的微博客社交网络,是微博、…

通过案例练习掌握SSH 的整合
1. SSH整合_方案01 ** 整合方案01 Struts2框架 Spring框架 在Spring框架中整合了Hibernate(JDBC亦可) 一些业务组件(Service组件)也可以放入Spring框架中迚行管理(昨天的例子) 1. 请求࿰…
tiny-cnn开源库的使用(MNIST)
tiny-cnn是一个基于CNN的开源库,它的License是BSD 3-Clause。作者也一直在维护更新,对进一步掌握CNN很有帮助,因此下面介绍下tiny-cnn在windows7 64bit vs2013的编译及使用。 1. 从https://github.com/nyanp/tiny-cnn下载源码࿱…

玩嗨的2亿快手“老铁”和幕后的极致视觉算法
作者 | Just出品 | AI科技大本营(ID:rgznai100)创立八年,短视频平台快手目前已经有超过两亿人在每天登陆使用,每天还有超过 1500 万条短视频被制作和上传,每天的累计观看数更是达到 150 亿。拥有如此庞大的用户数&…
lsmod命令详解
基础命令学习目录首页 原文链接:http://blog.sina.com.cn/s/blog_e6b2465d0101fuev.html lsmod——显示已载入系统的模块 lsmod 其实就是list modules的缩写,即 列出所有模块. 功能说明:显示已载入系统的模块。 语法:lsmod 说明&a…

javascript模块化、模块加载器初探
最常见网站的javascript架构可能是这样的: 一个底层框架文件,如jQuery一个网站业务框架文件,包含整站公用业务模块类(如弹框、ajax封装等)多个业务文件,包含每个具体页面有关系的业务代码为了减少一个HTTP请求,我们可能…

tiny-cnn执行过程分析(MNIST)
在http://blog.csdn.net/fengbingchun/article/details/50573841中以MNIST为例对tiny-cnn的使用进行了介绍,下面对其执行过程进行分析:支持两种损失函数:(1)、mean squared error(均方差);(2)、cross entropy(交叉熵)。在MNIST中使…

关于element的select多选选择器,数据回显的问题
关于element的select多选,数据回显的问题 在工作中遇到这样一个问题,新建表单时用element的select多选以后,在编辑的时候打开表单发现其他数据能正常显示,多选却无法正常回显。在网上找了很多后,终于解决了这个问题&am…

360金融发布Q2财报:净利6.92亿,同比增长114%,大数据与AI加持的科技服务是新亮点?
8月23日,360金融发布未经审计的2019年第二季度业绩报告。财务数据显示,2019年第二季度,360金融实现收入22.27亿元人民币,较2018年二季度9.79亿元增长128%;净利润为6.18亿元,而去年同期为净亏损1.42亿元&…

SPRING3.X JSON 406 和 中文乱码问题
2019独角兽企业重金招聘Python工程师标准>>> 简要 最近使用Spring3.2.3 版本 在使用 JSON message convertion 的时候,老是出现406 返回类型不匹配的问题,去网上google 了一番 也没有一个明确的说法,只能自己去调试。 Maven 依…
VLFeat开源库介绍及在VS2013中的编译
VLFeat是一个开源的计算机视觉算法库,内容主要包括feature detectors、feature extractors、k-means clustering、randomized kd-tree matching、super-pixelization。它是跨平台的,能够应用在Linux、Mac、Windows平台。它的License是BSD。 在VS2013中编…

人工智能写手,好用吗?
作者 | 王树义来源 | 玉树芝兰(ID:nkwangshuyi)1、印象之前给学生上课的时候,我介绍过利用循环神经网络,仿照作家风格进行创作的机器学习模型。不过,那模型写出来的东西嘛……我的评价是:望之&a…
表单系列之input number总结
各浏览器表现 <input type"number" /> chrome 除数字字符,只可输入e和.IE 除数字字符,其他字符均可输入,无报错Firefox 除数字字符,其他字符均可输入,但会报错移除箭头 //谷歌去除箭头 input::-webki…

Android中Service深入学习
概述 1、当用户在与当前应用程序不同的应用程序时,Service可以继续在后台运行。 2、Service可以让其他组件绑定,以便和它交互并进行进程间通信。 3、Service默认运行在创建它的应用程序的主线程中。 Service的使用主要是因为应用程序里面可能需要长时间地…
卷积神经网络(CNN)的简单实现(MNIST)
卷积神经网络(CNN)的基础介绍见http://blog.csdn.net/fengbingchun/article/details/50529500,这里主要以代码实现为主。CNN是一个多层的神经网络,每层由多个二维平面组成,而每个平面由多个独立神经元组成。以MNIST作为数据库,仿照…

Tensorflow源码解析5 -- 图的边 - Tensor
1 概述 前文两篇文章分别讲解了TensorFlow核心对象Graph,和Graph的节点Operation。Graph另外一大成员,即为其边Tensor。边用来表示计算的数据,它经过上游节点计算后得到,然后传递给下游节点进行运算。本文讲解Graph的边Tensor&…

物联网成网络安全防护新重点!
在昨天的 2019 北京网络安全大会上,工信部负责人表示,我国面向 5G 和车联网将建设网安防护体系,提升监测预警和应急响应能力。其中物联网设备已成为网安防护新重点。为什么工信部会这么重视物联网?物联网开发者的现状又是如何呢&a…

【分享】Java的几个重要词语
Java 是一种解释型语言,由SUN公司开发,基本上属于一个完全面向对象的语言,并且语言的设计仍然以简捷为重点。初学Java肯定会被一些名词给弄晕了,现在集中几个解释一下下。1、JVMJVM是Java Virtual Machine(Java虚拟机)的缩写&…
64位Ubuntu上编译32位程序操作步骤
1. 确认主机为64位架构的内核,应该输出为adm64,执行:$ dpkg --print-architecture2. 确认打开了多架构支持功能,应该输出为i386,执行:$ dpkg --print-foreign-architectures如果没有,…

分布式事务中间件 Fescar—RM 模块源码解读
2019独角兽企业重金招聘Python工程师标准>>> 前言 在SOA、微服务架构流行的年代,许多复杂业务上需要支持多资源占用场景,而在分布式系统中因为某个资源不足而导致其它资源占用回滚的系统设计一直是个难点。我所在的团队也遇到了这个问题&…

二维码检测哪家强?五大开源库测评比较
作者 | 周强来源 | 我爱计算机视觉(ID:aicvml)二维码已经进入人们的日常生活中,尤其是日本Denso Wave公司1994年发明的QR码,由于其易于检测、写入信息量大、提供强大的纠错机制,应用最为广泛,可…

linux 内核 出错-HP 方案
2019独角兽企业重金招聘Python工程师标准>>> SUPPORT COMMUNICATION - CUSTOMER ADVISORY Document ID: c03456595 Version: 1 Advisory: Red Hat Enterprise Linux 6 - "P4-Clockmod: Warning: EST-Capable CPU Detected" Messages Logged in /var/log…
Windows7 64bit VS2013 Caffe test MNIST操作步骤
在http://blog.csdn.net/fengbingchun/article/details/49849225中用Caffe对MNIST数据库进行训练,产生了model。下面介绍下如何将产生的model应用在实际的数字图像识别中。用到的测试图像与http://blog.csdn.net/fengbingchun/article/details/50573841中相同&#…
记住这35个英文单词,你就可以在RPA界混了!
无论是想玩转RPA(机器人流程自动化),还是有意了解、进入这项行业,只有先了解该领域的专有名词(行业术语),才能为之后的活动提供更多的可能。UiBot现为您编译整理了这份机器人流程自动化术语表&a…

福利 | 送你一张通往「2019 AI开发者大会」的门票
2019 AI开发者大会(AI ProCon 2019)是由中国IT社区CSDN主办的AI技术与产业年度盛会。多年经验淬炼,如今蓄势待发:2019年9月6-7日,大会将有近百位中美顶尖AI专家、知名企业代表以及千余名AI开发者齐聚北京,进行技术解读和产业论证。…

收缩日志文件夹
-- MSSQL2005 USE mastergo DECLARE dbname sysname;SET dbnameBSV100;-- 清空日志EXEC (DUMP TRANSACTION [dbname] WITH NO_LOG); -- 截断事务日志:EXEC (BACKUP LOG [dbname] WITH NO_LOG); -- 收缩数据库文件(如果不压缩,数据库的文件不会减小EXEC (DBCC SHR…