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.hppmodules/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 || floatif (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);elseflipHoriz(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 axisfor (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 axisfor (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函数的实现相关推荐

  1. OpenCV代码提取:cvtColor函数的实现

    OpenCV中的cvtColor函数包括了很多颜色格式之间的转换,用起来很方便,这里对cvtColor函数的code进行了提取,经测试,和OpenCV3.1结果完全一致. 实现代码cvtColor.h ...

  2. OpenCV代码提取:transpose函数的实现

    OpenCV中的transpose函数实现图像转置,公式为: 目前fbc_cv库中也实现了transpose函数,支持多通道,uchar和float两种数据类型,经测试,与OpenCV3.1结果完全一 ...

  3. 图像处理库(fbc_cv):源自OpenCV代码提取

    在实际项目中会经常用到一些基本的图像处理操作,而且经常拿OpenCV进行结果对比,因此这里从OpenCV中提取了一些代码组织成fbc_cv库.项目fbc_cv所有的代码已放到GitHub中,地址为   ...

  4. OpenCV代码提取:resize函数的实现

    之前在http://blog.csdn.net/fengbingchun/article/details/17335477 中有过对cv::resize函数五种插值算法的介绍.这里将OpenCV3.1 ...

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

    OpenCV中并没有直接提供实现rotate的函数,这里通过getRotationMatrix2D和warpAffine函数实现rotate,并增加了一个crop参数,用来判断是否进行crop.目前支 ...

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

    对OpenCV中的merge/split函数进行了实现,经测试,与OpenCV3.1结果完全一致. merge实现代码merge.hpp: // fbc_cv is free software and ...

  7. OpenCV代码提取:遍历指定目录下指定文件的实现

    OpenCV 3.1之前的版本,在contrib目录下有提供遍历文件的函数,用起来比较方便.但是在最新的OpenCV 3.1版本给去除掉了.为了以后使用方便,这里将OpenCV 2.4.9中相关的函数 ...

  8. OpenCV代码提取:Windows上通过DShow获取Camera视频

    在OpenCV 3.1中获取视频的模块在videoio(video input and output module)中,调用VideoCapture类接口,除了videoio模块外还依赖core.hi ...

  9. OpenCV 中的 remap 函数

    上一篇文章中提到 warpAffine 会分块处理,将坐标映射和插值系数分别存储下来,然后借助 remap 来实现最终的映射.而 remap 会根据映射关系取源像素并加权计算出目的像素值.其最核心的计 ...

最新文章

  1. python怎么输出浮点数_python 零基础入门教程第 2 章:基本数据类型 (一)
  2. CUBLAS_STATUS_ALLOC_FAILED CUDA_ERROR_OUT_OF_MEMORY
  3. 《最后期限》阅读笔记2
  4. 你知道Linux和Unix的区别吗
  5. mysql 大量数据 更改索引_一文看懂ICP原理--MySQL用索引去表里取数据的一种优化...
  6. Uniapp 导入 Vant 组件库
  7. mysql 存储过程 行锁_mysql存储过程出现锁表锁行的情况怎么解决?如:
  8. Django在根据models生成数据库表时报 __init__() missing 1 required positional argument: 'on_delete'...
  9. UVA1583 - Digit Generator
  10. ue 新建html,第四课 开发uehtml官网响应式静态页面(示例代码)
  11. jmeter TCP接口压力测试
  12. [对于蓝桥杯要说的一二体会]
  13. 【计算机网络】【应用层-5】
  14. phpadmin 导入数据
  15. python学习笔记十-文件操作
  16. 修改host文件实现内网传输
  17. 什么是硬件集成开发?硬件集成开发的核心有哪些?
  18. 【华为机试真题 Python】窗口滑动和最大值
  19. 业余草站长告诉你:网站被克隆了怎么办?
  20. Final Cut Pro X 快捷键

热门文章

  1. Halcon:(2)电路板检测实验
  2. Linux gcc 制作动/静态链接库
  3. kd-tree理论以及在PCL 中的代码的实现
  4. 报错You may use special comments to disable some warnings.vue-cli脚手架关闭eslint的步骤
  5. 在Ubuntu 14.04 64bit上安装批量图片处理器XnConvert
  6. PIXI 下落文字消除(3)
  7. 【MySQL解惑笔记】忘记MySQL数据库密码
  8. 基于QProbe创建基本Android图像处理框架
  9. SQL执行过程中的性能负载点
  10. 虚拟机下CentOS 6.5配置IP地址的三种方法