OpenCV代码提取:flip函数的实现
OpenCV中实现图像翻转的函数flip,公式为:
目前fbc_cv库中也实现了flip函数,支持多通道,uchar和float两种数据类型,经测试,与OpenCV3.1结果完全一致。
实现代码flip.hpp:
// fbc_cv is free software and uses the same licence as OpenCV // Email: fengbingchun@163.com #ifndef FBC_CV_FLIP_HPP_ #define FBC_CV_FLIP_HPP_ /* reference: include/opencv2/core.hpp modules/core/src/copy.cpp */ #include <typeinfo> #include "core/mat.hpp" namespace fbc { template<typename _Tp, int chs> static int flipHoriz(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst); template<typename _Tp, int chs> static int flipVert(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst); // Flips a 2D array around vertical, horizontal, or both axes // flipCode: 0 means flipping around the x - axis and positive value means flipping around y - axis. // Negative value means flipping around both axes // support type: uchar/float, multi-channels template <typename _Tp, int chs> int flip(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst, int flipCode) { FBC_Assert(typeid(uchar).name() == typeid(_Tp).name() || typeid(float).name() == typeid(_Tp).name()); // uchar || float if (dst.empty()) { dst = Mat_<_Tp, chs>(src.rows, src.cols); } else { FBC_Assert(src.rows == dst.rows && src.cols == dst.cols); } Size size = src.size(); if (flipCode < 0) { if (size.width == 1) flipCode = 0; if (size.height == 1) flipCode = 1; } if ((size.width == 1 && flipCode > 0) || (size.height == 1 && flipCode == 0) || (size.height == 1 && size.width == 1 && flipCode < 0)) { src.copyTo(dst); return 0; } if (flipCode <= 0) flipVert(src, dst); else flipHoriz(src, dst); if (flipCode < 0) flipHoriz(dst, dst); return 0; } template<typename _Tp, int chs> static int flipHoriz(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst) { Size size = src.size(); size_t esz = sizeof(_Tp) * chs; int i, j, limit = (int)(((size.width + 1) / 2) *esz ); AutoBuffer<int> _tab(size.width * esz); int* tab = _tab; size_t sstep = src.step; size_t dstep = dst.step; const uchar* src_ = src.ptr(); uchar* dst_ = dst.ptr(); for (i = 0; i < size.width; i++) { for (size_t k = 0; k < esz; k++) { tab[i*esz + k] = (int)((size.width - i - 1) * esz + k); } } for (; size.height--; src_ += sstep, dst_ += dstep) { for (i = 0; i < limit; i++) { j = tab[i]; uchar t0 = src_[i], t1 = src_[j]; dst_[i] = t1; dst_[j] = t0; } } return 0; } template<typename _Tp, int chs> static int flipVert(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst) { const uchar* src0 = src.ptr(); uchar* dst0 = dst.ptr(); Size size = src.size(); size_t sstep = src.step; size_t dstep = dst.step; size_t esz = sizeof(_Tp) * chs; const uchar* src1 = src0 + (size.height - 1)*sstep; uchar* dst1 = dst0 + (size.height - 1)*dstep; size.width *= (int)esz; for (int y = 0; y < (size.height + 1) / 2; y++, src0 += sstep, src1 -= sstep, dst0 += dstep, dst1 -= dstep) { int i = 0; if (((size_t)src0 | (size_t)dst0 | (size_t)src1 | (size_t)dst1) % sizeof(int) == 0) { for (; i <= size.width - 16; i += 16) { int t0 = ((int*)(src0 + i))[0]; int t1 = ((int*)(src1 + i))[0]; ((int*)(dst0 + i))[0] = t1; ((int*)(dst1 + i))[0] = t0; t0 = ((int*)(src0 + i))[1]; t1 = ((int*)(src1 + i))[1]; ((int*)(dst0 + i))[1] = t1; ((int*)(dst1 + i))[1] = t0; t0 = ((int*)(src0 + i))[2]; t1 = ((int*)(src1 + i))[2]; ((int*)(dst0 + i))[2] = t1; ((int*)(dst1 + i))[2] = t0; t0 = ((int*)(src0 + i))[3]; t1 = ((int*)(src1 + i))[3]; ((int*)(dst0 + i))[3] = t1; ((int*)(dst1 + i))[3] = t0; } for (; i <= size.width - 4; i += 4) { int t0 = ((int*)(src0 + i))[0]; int t1 = ((int*)(src1 + i))[0]; ((int*)(dst0 + i))[0] = t1; ((int*)(dst1 + i))[0] = t0; } } for (; i < size.width; i++) { uchar t0 = src0[i]; uchar t1 = src1[i]; dst0[i] = t1; dst1[i] = t0; } } return 0; } } // namespace fbc #endif // FBC_CV_FLIP_HPP_
测试代码test_flip.cpp:
#include "test_flip.hpp" #include <assert.h> #include <iostream> #include <string> #include <flip.hpp> #include <opencv2/opencv.hpp> int test_flip_uchar() { cv::Mat matSrc = cv::imread("E:/GitCode/OpenCV_Test/test_images/1.jpg", 1); if (!matSrc.data) { std::cout << "read image fail" << std::endl; return -1; } int width = matSrc.cols; int height = matSrc.rows; int flipCode[3] {-1, 0, 1}; // both axes, x axis, y axis for (int i = 0; i < 3; i++) { fbc::Mat_<uchar, 3> mat1(height, width, matSrc.data); fbc::Mat_<uchar, 3> mat2(height, width); fbc::flip(mat1, mat2, flipCode[i]); cv::Mat mat1_(height, width, CV_8UC3, matSrc.data); cv::Mat mat2_; cv::flip(mat1_, mat2_, flipCode[i]); assert(mat2.rows == mat2_.rows && mat2.cols == mat2_.cols && mat2.step == mat2_.step); for (int y = 0; y < mat2.rows; y++) { const fbc::uchar* p1 = mat2.ptr(y); const uchar* p2 = mat2_.ptr(y); for (int x = 0; x < mat2.step; x++) { assert(p1[x] == p2[x]); } } std::string name = std::to_string(i); std::string file_path = "E:/GitCode/OpenCV_Test/test_images/"; std::string name_fbc = file_path + "flip_fbc_" + name + ".jpg"; std::string name_cv = file_path + "flip_cv_" + name + ".jpg"; cv::Mat matSave(height, width, CV_8UC3, mat2.data); cv::imwrite(name_fbc, matSave); cv::imwrite(name_cv, mat2_); } return 0; } int test_flip_float() { cv::Mat matSrc = cv::imread("E:/GitCode/OpenCV_Test/test_images/1.jpg", 1); if (!matSrc.data) { std::cout << "read image fail" << std::endl; return -1; } cv::cvtColor(matSrc, matSrc, CV_BGR2GRAY); matSrc.convertTo(matSrc, CV_32FC1); int width = matSrc.cols; int height = matSrc.rows; int flipCode[3] {-1, 0, 1}; // both axes, x axis, y axis for (int i = 0; i < 3; i++) { fbc::Mat_<float, 1> mat1(height, width, matSrc.data); fbc::Mat_<float, 1> mat2(height, width); fbc::flip(mat1, mat2, flipCode[i]); cv::Mat mat1_(height, width, CV_32FC1, matSrc.data); cv::Mat mat2_; cv::flip(mat1_, mat2_, flipCode[i]); assert(mat2.rows == mat2_.rows && mat2.cols == mat2_.cols && mat2.step == mat2_.step); for (int y = 0; y < mat2.rows; y++) { const fbc::uchar* p1 = mat2.ptr(y); const uchar* p2 = mat2_.ptr(y); for (int x = 0; x < mat2.step; x++) { assert(p1[x] == p2[x]); } } } return 0; }
GitHub:https://github.com/fengbingchun/OpenCV_Test
OpenCV代码提取:flip函数的实现的更多相关文章
- OpenCV代码提取:transpose函数的实现
OpenCV中的transpose函数实现图像转置,公式为: 目前fbc_cv库中也实现了transpose函数,支持多通道,uchar和float两种数据类型,经测试,与OpenCV3.1结果完全一 ...
- OpenCV代码提取:dft函数的实现
The Fourier Transform will decompose an image into its sinus and cosines components. In other words, ...
- OpenCV代码提取: threshold函数的实现
threshold algorithm: The simplest image segmentation method. All thresholding algorithms take a sour ...
- OpenCV代码提取:遍历指定目录下指定文件的实现
前言 OpenCV 3.1之前的版本,在contrib目录下有提供遍历文件的函数,用起来比较方便.但是在最新的OpenCV 3.1版本给去除掉了.为了以后使用方便,这里将OpenCV 2.4.9中相关 ...
- opencv: flip函数的使用;
flip函数用于图像翻转,比较方便.在opencv中有几种形式: C++: void flip(InputArray src, OutputArray dst, int flipCode) Pytho ...
- OpenCV中的绘图函数-OpenCV步步精深
OpenCV 中的绘图函数 画线 首先要为画的线创造出环境,就要生成一个空的黑底图像 img=np.zeros((512,512,3), np.uint8) 这是黑色的底,我们的画布,我把窗口名叫做i ...
- 基础学习笔记之opencv(24):imwrite函数的使用
http://www.cnblogs.com/tornadomeet/archive/2012/12/26/2834336.html 前言 OpenCV中保存图片的函数在c++版本中变成了imwrit ...
- (转)Uri详解之——Uri结构与代码提取
前言:依然没有前言…… 相关博客:1.<Uri详解之——Uri结构与代码提取>2.<Uri详解之二——通过自定义Uri外部启动APP与Notification启动> 上几篇给大 ...
- Uri详解之——Uri结构与代码提取
目录(?)[+] 前言:依然没有前言…… 相关博客:1.<Uri详解之——Uri结构与代码提取>2.<Uri详解之二——通过自定义Uri外部启动APP与Notification启动& ...
随机推荐
- 时间序列算法理论及python实现(1-算法理论部分)
如果你在寻找时间序列是什么?如何实现时间序列?那么请看这篇博客,将以通俗易懂的语言,全面的阐述时间序列及其python实现. 就餐饮企业而言,经常会碰到如下问题. 由于餐饮行业是胜场和销售同时进行的, ...
- ubuntu 可以加速播放的播放器SMPlayer 16.4安装
直接贴命令 sudo apt-add-repository ppa:rvm/smplayer sudo apt-get update sudo apt-get install smplayer smp ...
- kill 使用当前数据库的所有session
--在维护中经常需要将某一数据库所有进程都杀掉,手工杀有点太费事.写了一个存储过程 --usage:proc_kill 'PSADBA' create proc proc_kill(@db varch ...
- 【[NOI2003]文本编辑器】
题目 发现这样一句话就会导致\(T\) ch[m][0]=++m; 并不是很知道为什么,可能这是某种未定义行为在不同编译器下会有不同后果? 至于这道题就很简单了,几个有关光标位置的操作就用一个变量模拟 ...
- SpringMVC学习记录二——非注解和注解的处理器映射器和适配器
3 非注解的处理器映射器和适配器 3.1 非注解的处理器映射器 处理器映射器: org.springframework.web.servlet.handler.BeanNameUr ...
- java随机数Reandom(简单介绍)
简单介绍 Java中存在着两种Random函数 一.java.lang.Math.Random; 调用这个Math.Random()函数能够返回带正号的double值,该值大于等于0.0且小于1.0, ...
- 【luogu P1462 通往奥格瑞玛的道路】 题解
题目链接:https://www.luogu.org/problemnew/show/P1462 记住HP=0也叫死. #include <queue> #include <cstd ...
- 数据库优先生成EF CRUD演示
①准备我们的数据库: Northwind ②新建 实体数据模型,由数据库优先创建 ③创建控制器,这里我们只针对了Customers这张表做演示,实际会复杂的多 注:你可以把上面两步合成一步来写,创建控 ...
- c++cmb
#include<windows.h> #include<bits/stdc++.h> using namespace std; ]; int main() { printf( ...
- BZOJ1030: [JSOI2007]文本生成器(AC自动机)
Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 5984 Solved: 2523[Submit][Status][Discuss] Descripti ...