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启动& ...
随机推荐
- scrum 第四次冲刺
一.项目目的 为生活在长大的学生提供方快捷的生活服务,通过帖子发现自己志同道合的朋友,记录自己在长大点滴.本项目的意义在于锻炼团队的scrum能力,加强团队合作能力.确定本项目采用的技术方向:本项目整 ...
- python入门18 继承和多态
继承:子类继承父类的属性和方法 class 子类名(父类1,父类2) 多态:子类重写父类的方法 判断对象是否是某个类的实例: isinstance(object,class) 父类-汽车类 #co ...
- UNIX PIPES 管道原稿
40年前,Unix操作系统横空出世,Unix不仅仅带来了一个操作系统,还创造C语言,Socket,开源,黑客等等文化,这些文化影响着整个计算机世界的文明,直到今天. 如果说Unix是计算机文明中最伟大 ...
- Type Syntax error, insert ")" to complete Expression
今天倒持了 几个小时! 愣是 没有明确 ,为什么我的JSP的第一行没有代码? 还是报错! 错误是: Description Resource Path Location Type Sy ...
- 【LOJ2461】「2018 集训队互测 Day 1」完美的队列(分块+双指针)
点此看题面 大致题意: 让你维护\(n\)个有限定长度的队列,每次区间往队列里加数,求每次加完后的队列里剩余元素种类数. 核心思路 这道题可以用分块+双指针去搞. 考虑求出每个操作插入的元素在队列中被 ...
- E. XOR and Favorite Number
题意:很多询问,求每个询问下,有多少个区间,异或=k. 分析:异或也有前缀和.[L,R] = pre[R] ^ pre[L-1]: 莫队算法:是莫涛队长发明的,一种改良版的暴力离线算法. 首先将问题重 ...
- 剑指offer23 从上往下打印二叉树
没有把队列的头部弹出,出现内存错误:
- DEM、DTM和DSM的区别
一.DTM(Digital Terrain Model) 数字地面模型是利用一个任意坐标系中大量选择的已知x.y.z的坐标点对连续地面的一个简单的统计表示,或者说,DTM就是地形表面形态属性信息的数字 ...
- Mysql索引学习笔记
1.btree索引与hash索引 下列范围查询适用于 btree索引和hash索引: SELECT * FROM t1 WHERE key_col = 1 OR key_col IN (15,18,2 ...
- 【洛谷P2296】[NOIP2014]寻找道路
寻找道路 题目链接 这道题非常的水,按照题意, 先反向建边,从终点搜索,标记出可以到达终点的点 然后枚举一遍,判断出符合条件1的点 再从起点搜索一遍就可以了 #include<iostream& ...