当前位置: 首页 > 编程日记 > 正文

OpenCV代码提取:merge/split函数的实现

对OpenCV中的merge/split函数进行了实现,经测试,与OpenCV3.1结果完全一致。

merge实现代码merge.hpp:

// fbc_cv is free software and uses the same licence as OpenCV
// Email: fengbingchun@163.com#ifndef FBC_CV_MERGE_HPP_
#define FBC_CV_MERGE_HPP_/* reference: include/opencv2/core.hppcore/src/convert.cppcore/src/merge.cpp
*/#include <vector>
#include "core/mat.hpp"#ifndef __cplusplus#error merge.hpp header must be compiled as C++
#endifnamespace fbc {// merge several arrays to make a single multi-channel array
template<typename _Tp, int chs1, int chs2>
int merge(const std::vector<Mat_<_Tp, chs1>>& src, Mat_<_Tp, chs2>& dst)
{FBC_Assert(dst.data != NULL);FBC_Assert((src.size() > 0) && (src.size() == dst.channels) && (src.size() <= FBC_CN_MAX));int width = src[0].cols;int height = src[0].rows;FBC_Assert((dst.cols == width) && (dst.rows == height));for (int i = 0; i < src.size(); i++) {FBC_Assert(src[i].data != NULL);FBC_Assert((src[i].cols == width) && src[i].rows == height);FBC_Assert(src[i].channels == 1);}if (src.size() == 1) {memcpy(dst.data, src[0].data, dst.step * dst.rows);return 0;}_Tp* pDst = (_Tp*)dst.data;int len = width * height;int cn = dst.channels;for (int i = 0; i < src.size(); i++) {_Tp* pSrc = (_Tp*)src[i].data;for (int j = 0; j < len; j++) {pDst[j * cn + i] = pSrc[j];}}return 0;
}} // namespace fbc#endif // FBC_CV_MERGE_HPP_
split实现代码split.hpp:

// fbc_cv is free software and uses the same licence as OpenCV
// Email: fengbingchun@163.com#ifndef FBC_CV_SPLIT_HPP_
#define FBC_CV_SPLIT_HPP_/* reference: include/opencv2/core.hppcore/src/convert.cppcore/src/split.cpp
*/#include <vector>
#include "core/mat.hpp"#ifndef __cplusplus#error split.hpp header must be compiled as C++
#endifnamespace fbc {// split a multi-channel array into separate single-channel arrays
template<typename _Tp, int chs1, int chs2>
int split(const Mat_<_Tp, chs1>& src, std::vector<Mat_<_Tp, chs2>>& dst)
{FBC_Assert(src.data != NULL);FBC_Assert((dst.size() == chs1) && (chs2 == 1));for (int i = 0; i < dst.size(); i++) {FBC_Assert((dst[i].data != NULL) && (dst[i].rows == src.rows) && (dst[i].cols == src.cols));}int cn = src.channels;if (cn == 1) {memcpy(dst[0].data, src.data, src.step * src.rows);return 0;}_Tp* pSrc = (_Tp*)src.data;int len = src.rows * src.cols;for (int i = 0; i < cn; i++) {_Tp* pDst = (_Tp*)dst[i].data;for (int j = 0; j < len; j++) {pDst[j] = pSrc[j * cn + i];}}return 0;
}} // namespace fbc#endif // FBC_CV_SPLIT_HPP_
merge测试代码:

#include <assert.h>
#include <vector>
#include <core/mat.hpp>
#include <merge.hpp>#include <opencv2/opencv.hpp>#include "test_merge.hpp"int test_merge_uchar()
{cv::Mat matSrc1 = cv::imread("E:/GitCode/OpenCV_Test/test_images/lena.png", 1);cv::Mat matSrc2 = cv::imread("E:/GitCode/OpenCV_Test/test_images/1.jpg", 1);cv::Mat matSrc3 = cv::imread("E:/GitCode/OpenCV_Test/test_images/2.jpg", 1);if (!matSrc1.data || !matSrc2.data || !matSrc3.data) {std::cout << "read image fail" << std::endl;return -1;}int width = 500, height = 600;cv::cvtColor(matSrc1, matSrc1, CV_BGR2GRAY);cv::cvtColor(matSrc2, matSrc2, CV_BGR2GRAY);cv::cvtColor(matSrc3, matSrc3, CV_BGR2GRAY);cv::resize(matSrc1, matSrc1, cv::Size(width, height));cv::resize(matSrc2, matSrc2, cv::Size(width, height));cv::resize(matSrc3, matSrc3, cv::Size(width, height));fbc::Mat_<fbc::uchar, 1> mat1(height, width, matSrc1.data);fbc::Mat_<fbc::uchar, 1> mat2(height, width, matSrc2.data);fbc::Mat_<fbc::uchar, 1> mat3(height, width, matSrc3.data);std::vector<fbc::Mat_<fbc::uchar, 1>> mat;mat.push_back(mat1);mat.push_back(mat2);mat.push_back(mat3);fbc::Mat_<fbc::uchar, 3> matDst(height, width);fbc::merge(mat, matDst);std::vector<cv::Mat> mat_;mat_.push_back(matSrc1);mat_.push_back(matSrc2);mat_.push_back(matSrc3);cv::Mat matDst_;cv::merge(mat_, matDst_);assert(matDst.channels == matDst_.channels());assert((matDst.rows == matDst_.rows) && (matDst.cols == matDst_.cols));assert(matDst.step == matDst_.step);for (int i = 0; i < matDst.rows; i++) {const fbc::uchar* p1 = matDst.ptr(i);const uchar* p2 = matDst_.ptr(i);for (int j = 0; j < matDst.step; j++) {assert(p1[j] == p2[j]);}}return 0;
}int test_merge_float()
{cv::Mat matSrc1 = cv::imread("E:/GitCode/OpenCV_Test/test_images/lena.png", 1);cv::Mat matSrc2 = cv::imread("E:/GitCode/OpenCV_Test/test_images/1.jpg", 1);cv::Mat matSrc3 = cv::imread("E:/GitCode/OpenCV_Test/test_images/2.jpg", 1);if (!matSrc1.data || !matSrc2.data || !matSrc3.data) {std::cout << "read image fail" << std::endl;return -1;}int width = 500, height = 600;cv::cvtColor(matSrc1, matSrc1, CV_BGR2GRAY);cv::cvtColor(matSrc2, matSrc2, CV_BGR2GRAY);cv::cvtColor(matSrc3, matSrc3, CV_BGR2GRAY);cv::resize(matSrc1, matSrc1, cv::Size(width, height));cv::resize(matSrc2, matSrc2, cv::Size(width, height));cv::resize(matSrc3, matSrc3, cv::Size(width, height));matSrc1.convertTo(matSrc1, CV_32FC1);matSrc2.convertTo(matSrc2, CV_32FC1);matSrc3.convertTo(matSrc3, CV_32FC1);fbc::Mat_<float, 1> mat1(height, width, matSrc1.data);fbc::Mat_<float, 1> mat2(height, width, matSrc2.data);fbc::Mat_<float, 1> mat3(height, width, matSrc3.data);std::vector<fbc::Mat_<float, 1>> mat;mat.push_back(mat1);mat.push_back(mat2);mat.push_back(mat3);fbc::Mat_<float, 3> matDst(height, width);fbc::merge(mat, matDst);std::vector<cv::Mat> mat_;mat_.push_back(matSrc1);mat_.push_back(matSrc2);mat_.push_back(matSrc3);cv::Mat matDst_;cv::merge(mat_, matDst_);assert(matDst.channels == matDst_.channels());assert((matDst.rows == matDst_.rows) && (matDst.cols == matDst_.cols));assert(matDst.step == matDst_.step);for (int i = 0; i < matDst.rows; i++) {const fbc::uchar* p1 = matDst.ptr(i);const uchar* p2 = matDst_.ptr(i);for (int j = 0; j < matDst.step; j++) {assert(p1[j] == p2[j]);}}return 0;
}
split测试代码:

#include <assert.h>
#include <vector>
#include <core/mat.hpp>
#include <split.hpp>#include <opencv2/opencv.hpp>#include "test_split.hpp"int test_split_uchar()
{cv::Mat mat = cv::imread("E:/GitCode/OpenCV_Test/test_images/lena.png", 1);if (!mat.data) {std::cout << "read image fail" << std::endl;return -1;}//cv::cvtColor(mat, mat, CV_BGR2GRAY);int chs = mat.channels();int width = mat.cols;int height = mat.rows;fbc::Mat_<fbc::uchar, 3> mat1(height, width, mat.data);std::vector<fbc::Mat_<fbc::uchar, 1>> vecMat2;fbc::Mat_<fbc::uchar, 1>* mat2 = new fbc::Mat_<fbc::uchar, 1>[chs];for (int i = 0; i < chs; i++) {mat2[i] = fbc::Mat_<fbc::uchar, 1>(height, width);vecMat2.push_back(mat2[i]);}fbc::split(mat1, vecMat2);cv::Mat mat1_(height, width, CV_8UC3, mat.data);std::vector<cv::Mat> vecMat2_;cv::split(mat1_, vecMat2_);assert(vecMat2.size() == vecMat2_.size());for (int i = 0; i < vecMat2.size(); i++) {assert(vecMat2[i].rows == vecMat2_[i].rows && vecMat2[i].cols == vecMat2_[i].cols);assert(vecMat2[i].step == vecMat2_[i].step);assert(vecMat2[i].channels == vecMat2_[i].channels());for (int y = 0; y < vecMat2[i].rows; y++) {const fbc::uchar* p = vecMat2[i].ptr(y);const uchar* p_ = vecMat2_[i].ptr(y);for (int x = 0; x < vecMat2[i].step; x++) {assert(p[x] == p_[x]);}}}delete[] mat2;return 0;
}int test_split_float()
{cv::Mat mat = cv::imread("E:/GitCode/OpenCV_Test/test_images/lena.png", 1);if (!mat.data) {std::cout << "read image fail" << std::endl;return -1;}mat.convertTo(mat, CV_32FC3);//cv::cvtColor(mat, mat, CV_BGR2GRAY);int chs = mat.channels();int width = mat.cols;int height = mat.rows;fbc::Mat_<float, 3> mat1(height, width, mat.data);std::vector<fbc::Mat_<float, 1>> vecMat2;fbc::Mat_<float, 1>* mat2 = new fbc::Mat_<float, 1>[chs];for (int i = 0; i < chs; i++) {mat2[i] = fbc::Mat_<float, 1>(height, width);vecMat2.push_back(mat2[i]);}fbc::split(mat1, vecMat2);cv::Mat mat1_(height, width, CV_32FC3, mat.data);std::vector<cv::Mat> vecMat2_;cv::split(mat1_, vecMat2_);assert(vecMat2.size() == vecMat2_.size());for (int i = 0; i < vecMat2.size(); i++) {assert(vecMat2[i].rows == vecMat2_[i].rows && vecMat2[i].cols == vecMat2_[i].cols);assert(vecMat2[i].step == vecMat2_[i].step);assert(vecMat2[i].channels == vecMat2_[i].channels());for (int y = 0; y < vecMat2[i].rows; y++) {const fbc::uchar* p = vecMat2[i].ptr(y);const uchar* p_ = vecMat2_[i].ptr(y);for (int x = 0; x < vecMat2[i].step; x++) {assert(p[x] == p_[x]);}}}delete[] mat2;return 0;
}

GitHub: https://github.com/fengbingchun/OpenCV_Test



相关文章:

DeepMind提图像生成的递归神经网络DRAW,158行Python代码复现

作者 | Samuel Noriega译者 | Freesia编辑 | 夕颜出品 | AI科技大本营&#xff08;ID: rgznai100&#xff09;【导读】最近&#xff0c;谷歌 DeepMInd 发表论文( DRAW: A Recurrent Neural Network For Image Generation&#xff09;&#xff0c;提出了一个用于图像生成的递归神…

其他进制的数字

JS中如果需要表示16进制的数字,则需要以0X开头 0X10 八进制数字以0开头 070 070有些浏览器会以8进制解析,但是有些则用10进制解析,10进制为70,8进制为56 所以parseint() 第二个参数可以设定进制,比如 parseint(“070”,10)代表以10进制解析070 2进制以0b开头,但是不是所有浏览…

java中的移位运算符

移位运算符是在数字的二进制形式上进行平移。主要有左移&#xff08;<<&#xff09;、带符号右移&#xff08;>>&#xff09;以及无符号右移&#xff08;>>>&#xff09;。左移运算符&#xff08;<<&#xff09;的运算规则为&#xff1a;按二进制形…

C++11中nullptr的使用

在C语言中&#xff0c;NULL实际上是一个void* 的指针&#xff0c;然后把void* 指针赋值给其它类型的指针的时候&#xff0c;会隐式转换成相应的类型。而如果用一个C编译器来编译的时候是要出错的&#xff0c;因为C是强类型的&#xff0c;void* 是不能隐式转换成其它指针类型的。…

埃森哲、亚马逊和万事达卡抱团推出的区块链项目有何神通?

据外媒报道&#xff0c;今日埃森哲宣布了一项新的区块链项目&#xff0c;该项目为基于区块链的循环供应链&#xff0c;将与万事达卡和亚马逊共同合作。据官方介绍&#xff0c;这个基于区块链的循环供应链能够让客户识别供应链上的小规模供应商和种植者&#xff0c;例如&#xf…

小团队如何玩转物联网开发?

近几年来&#xff0c;物联网发展迅速&#xff1a;据中商产业研究院《2016——2021年中国物联网产业市场研究报告》显示&#xff0c;预计到2020年&#xff0c;中国物联网的整体规模将达2.2万亿元&#xff0c;产业规模比互联网大30倍。与之相反的是&#xff0c;物联网开发者在开发…

Build Boost C++ libraries for x32/x64 VC++ compilers on Windows

2019独角兽企业重金招聘Python工程师标准>>> Boost is a set of libraries for the C programming language that provide support for tasks and structures such as linear algebra, pseudorandom number generation, multithreading, image processing, regular …

C++11中auto的使用

在C语言中&#xff0c;就有了auto关键字&#xff0c;它被当作是一个变量的存储类型修饰符&#xff0c;表示自动变量(局部变量)。它不能被单独使用&#xff0c;否则编译器会给出警告。在C11标准中&#xff0c;添加了新的类型推导特性。在C 11中&#xff0c;使用auto定义的变量不…

攻和防谁更厉害?AI技术在恶意软件检测中的应用和对抗

AI技术的发展为网络安全带来新机遇的同时&#xff0c;黑客也在逐渐利用AI漏洞建立对抗样本以躲避攻击&#xff0c;双方在各自领域的更多尝试也将是AI技术发展的一场新博弈。那么&#xff0c;在应用中&#xff0c;如何利用AI检测技术与恶意软件展开对抗&#xff1f; 腾讯安全技术…

一文看懂机器学习中的常用损失函数

作者丨stephenDC编辑丨zandy来源 | 大数据与人工智能&#xff08;ID: ai-big-data&#xff09;导语&#xff1a;损失函数虽然简单&#xff0c;却相当基础&#xff0c;可以看做是机器学习的一个组件。机器学习的其他组件&#xff0c;还包括激活函数、优化器、模型等。本文针对机…

Using Apache2 with JBoss AS7 on Ubuntu

大体思路同《Using Apache Web Server with Jboss AS 7》一致&#xff0c;但在Ubuntu上的操作与之前有些区别。 这里仍然演示mod_proxy的配置。 首先加载相应的模块。Ubuntu中加载模块和卸载模块均可以通过命令操作&#xff0c;与其对应的命令分别是a2enmod和a2dismod。 启用…

OpenCV代码提取:rotate函数的实现

OpenCV中并没有直接提供实现rotate的函数&#xff0c;这里通过getRotationMatrix2D和warpAffine函数实现rotate&#xff0c;并增加了一个crop参数&#xff0c;用来判断是否进行crop。目前支持uchar和float两种类型&#xff0c;经测试&#xff0c;与OpenCV3.1结果完全一致。公式…

在 Node.js 中用子进程操作标准输入/输出

翻译&#xff1a;疯狂的技术宅原文&#xff1a;http://2ality.com/2018/05/chi... 本文首发微信公众号&#xff1a;jingchengyideng欢迎关注&#xff0c;每天都给你推送新鲜的前端技术文章 在本中&#xff0c;我们在 Node.js 中把 shell 命令作为子进程运行。然后异步读取这些进…

再见,Python 2.x

整理 | 屠敏来源 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;在技术的长河中&#xff0c;软件、工具、系统等版本的迭代本是常事&#xff0c;但由于使用习惯、版本的兼容性、易用性等因素&#xff0c;很多用户及开发者在使用或做开发的过程中&#xff0c;并不愿意及…

Android UI系列-----CheckBox和RadioButton(1)

主要记录一下CheckBox多选框和RadioGroup、RadioButton单选框的设置以及注册监听器 1.CheckBox 布局文件&#xff1a; <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"android…

C++中struct的使用

C语言继承了C语言的struct&#xff0c;并且加以扩充。在C语言中struct是只能定义数据成员&#xff0c;而不能定义成员函数的。而在C中&#xff0c;struct类似于class&#xff0c;在其中既可以定义数据成员&#xff0c;又可以定义成员函数。结构类型是用户定义的复合类型&#x…

填报表中也可以添加 html 事件

在实际的项目开发中&#xff0c;填报表的应用十分广泛。 多数情况下&#xff0c;填报表会作为整个项目的一部分配合需求灵活使用&#xff0c;但有时也会受大项目环境的影响&#xff0c;产生一些特别的要求。比如&#xff0c;通常报表单元格的数据类型大多是文本&#xff0c;有时…

60+业内技术专家,9大核心技术专题,AI ProCon倒计时一周!

2018 年&#xff0c;由 CSDN 举办的第一届 AI 开发者大会喊出“只讲技术&#xff0c;拒绝空谈”&#xff0c;两天会议时间&#xff0c;国内外几十家顶尖科技企业讲述了其主流技术及其应用案例&#xff0c;真正引领国内开发者紧跟技术浪潮。一年过去&#xff0c;在你还未有所觉察…

密码学研究-数字签名

引入&#xff1a;提到签名&#xff0c;大家都不陌生&#xff0c;大家知道&#xff0c;重大的文件一般都要领导签名&#xff0c;来确保这个文件的真实有效。而一些比较重要的合同&#xff0c;比如买房的购房合同&#xff0c;都要盖“骑缝章”&#xff0c;这个骑缝章&#xff0c;…

C++11中shared_ptr的使用

在C中&#xff0c;动态内存的管理是通过一对运算符来完成的&#xff1a;new&#xff0c;在动态内存中为对象分配空间并返回一个指向该对象的指针&#xff0c;可以选择对对象进行初始化&#xff1b;delete&#xff0c;接受一个动态对象的指针&#xff0c;销毁该对象&#xff0c;…

colly源码学习

colly源码学习 colly是一个golang写的网络爬虫。它使用起来非常顺手。看了一下它的源码&#xff0c;质量也是非常好的。本文就阅读一下它的源码。 使用示例 func main() {c : colly.NewCollector()// Find and visit all linksc.OnHTML("a[href]", func(e *colly.HTM…

可惜了,你们只看到“双马会”大型尬聊

作者 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;导读&#xff1a;2019 年 8 月 29 日&#xff0c;世界人工智能大会&#xff08;WAIC&#xff09;在上海正式拉开帷幕。开幕式上&#xff0c;最让人瞩目的莫过于阿里巴巴前 CEO 马云与特斯拉 CEO Elon Musk …

Java 过滤特殊字符的 正则表达式

Java正则表达式学习&#xff1a; 因为正则表达式是一个很庞杂的体系&#xff0c;此例仅举些入门的概念&#xff0c;更多的请参阅相关书籍及自行摸索。 \\ 反斜杠 \t 间隔 (\u0009) \n 换行 (\u000A) \r 回车 (\u000D) \d 数字 等价于[0-9] \D 非数字 等价于[^0-9] \s 空…

C++11中unique_ptr的使用

在C中&#xff0c;动态内存的管理是通过一对运算符来完成的&#xff1a;new&#xff0c;在动态内存中为对象分配空间并返回一个指向该对象的指针&#xff0c;可以选择对对象进行初始化&#xff1b;delete&#xff0c;接受一个动态对象的指针&#xff0c;销毁该对象&#xff0c;…

从这篇YouTube论文,剖析强化学习在工业级场景推荐系统中的应用

作者 | 吴海波转载自知乎用户吴海波【导读】本文作者根据两篇工业界背景的论文解答了 RL 在推荐场景需要解决的问题与困难&#xff0c;以及入门需要学习得相关知识点。2 个月前&#xff0c;业界开始流传 youtube 成功将 RL 应用在了推荐场景&#xff0c;并且演讲者在视频中说是…

java中两个Integer类型的值相比较的问题

转载自&#xff1a; https://www.cnblogs.com/xh0102/p/5280032.html 两个Integer类型整数进行比较时&#xff0c;一定要先用intValue()方法将其转换为int数之后再进行比较&#xff0c;因为直接使用比较两个Integer会出现问题。 总结&#xff1a; 当给Integer直接赋值时&#x…

C#共享内存实例 附源码

原文 C#共享内存实例 附源码 网上有C#共享内存类&#xff0c;不过功能太简单了&#xff0c;并且写内存每次都从开头写。故对此进行了改进&#xff0c;并做了个小例子&#xff0c;供需要的人参考。 主要改进点&#xff1a; 通过利用共享内存的一部分空间(以下称为“数据信息区”…

C++11中weak_ptr的使用

在C中&#xff0c;动态内存的管理是通过一对运算符来完成的&#xff1a;new&#xff0c;在动态内存中为对象分配空间并返回一个指向该对象的指针&#xff0c;可以选择对对象进行初始化&#xff1b;delete&#xff0c;接受一个动态对象的指针&#xff0c;销毁该对象&#xff0c;…

经典不过时,回顾DeepCompression神经网络压缩

作者 | 薰风初入弦转载自知乎导读&#xff1a;本文作者为我们详细讲述了 ICLR 2016 的最佳论文 Deep Compression 中介绍的神经网络压缩方法。神经网络压缩一直是一个重要的研究方向&#xff0c;而目前业界最认可的压缩方法莫过于 ICLR 2016 的最佳论文 Deep Compression&#…

区块链技术特点之去中心化特性

想知道更多关于区块链技术知识&#xff0c;请百度【链客区块链技术问答社区】 链客&#xff0c;有问必答&#xff01;&#xff01; 由于区块链技术去中心化的特性&#xff0c;其在我们生活中的很多重要领域&#xff08;如金融、管理&#xff09;等方面具有重要的意义。例如&…