OpenCV中的transpose函数实现图像转置,公式为:

目前fbc_cv库中也实现了transpose函数,支持多通道,uchar和float两种数据类型,经测试,与OpenCV3.1结果完全一致。

实现代码transpose.hpp:

// fbc_cv is free software and uses the same licence as OpenCV
// Email: fengbingchun@163.com

#ifndef FBC_CV_TRANSPOSE_HPP_
#define FBC_CV_TRANSPOSE_HPP_

/* reference: include/opencv2/core.hpp
              modules/core/src/matrix.cpp
*/

#include <typeinfo>
#include "core/mat.hpp"

namespace fbc {

// transposes the matrix
// \f[\texttt{dst} (i,j) =  \texttt{src} (j,i)\f]
// support type: uchar/float, multi-channels
template <typename _Tp, int chs>
int transpose(const Mat_<_Tp, chs>& src, Mat_<_Tp, chs>& dst)
{
	FBC_Assert(typeid(uchar).name() == typeid(_Tp).name() || typeid(float).name() == typeid(_Tp).name()); // uchar || float
	if (dst.empty()) {
		dst = Mat_<_Tp, chs>(src.cols, src.rows);
	} else {
		FBC_Assert(src.rows == dst.cols && src.cols == dst.rows);
	}

	if (src.empty()) {
		dst.release();
		return 0;
	}

	// handle the case of single-column/single-row matrices, stored in STL vectors.
	if (src.rows != dst.cols || src.cols != dst.rows) {
		FBC_Assert(src.size() == dst.size() && (src.cols == 1 || src.rows == 1));
		src.copyTo(dst);
		return 0;
	}

	if (dst.data == src.data) {
		FBC_Assert(dst.cols == dst.rows);
		int n = dst.rows;
		int  step = dst.step;
		uchar* data = dst.ptr();

		for (int i = 0; i < n; i++) {
			_Tp* row = (_Tp*)(data + step*i);
			int i_ = i * chs;

			for (int j = i + 1; j < n; j++) {
				_Tp* data1 = (_Tp*)(data + step * j);
				int j_ = j * chs;

				for (int ch = 0; ch < chs; ch++) {
					std::swap(row[j_ + ch], data1[i_ + ch]);
				}
			}
		}
	} else {
		const uchar* src_ = src.ptr();
		size_t sstep = src.step;
		uchar* dst_ = dst.ptr();
		size_t dstep = dst.step;
		int m = src.cols, n = src.rows;

		for (int i = 0; i < n; i++) {
			const _Tp* s = (const _Tp*)(src_ + sstep*i);
			int i_ = i * chs;

			for (int j = 0; j < m; j++) {
				_Tp* d = (_Tp*)(dst_ + dstep*j);
				int j_ = j * chs;

				for (int ch = 0; ch < chs; ch++) {
					d[i_ + ch] = s[j_ + ch];
				}
			}
		}
	}

	return 0;
}

} // namespace fbc

#endif // FBC_CV_TRANSPOSE_HPP_

测试代码test_transpose.cpp:

#include "test_transpose.hpp"
#include <assert.h>
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
#include <transpose.hpp>

int test_transpose_uchar()
{
	cv::Mat matSrc = cv::imread("E:/GitCode/OpenCV_Test/test_images/lena.png", 1);
	if (!matSrc.data) {
		std::cout << "read image fail" << std::endl;
		return -1;
	}

	int width = matSrc.cols;
	int height = matSrc.rows;
	cv::Mat matSrc_;
	cv::resize(matSrc, matSrc_, cv::Size(width, width));

	fbc::Mat_<uchar, 3> mat1(width, width);
	memcpy(mat1.data, matSrc_.data, width * width * 3);
	fbc::transpose(mat1, mat1);

	cv::Mat mat1_(width, width, CV_8UC3);
	memcpy(mat1_.data, matSrc_.data, width * width * 3);
	cv::transpose(mat1_, mat1_);

	assert(mat1.rows == mat1_.rows && mat1.cols == mat1_.cols && mat1.step == mat1_.step);
	for (int y = 0; y < mat1.rows; y++) {
		const fbc::uchar* p1 = mat1.ptr(y);
		const uchar* p2 = mat1_.ptr(y);

		for (int x = 0; x < mat1.step; x++) {
			assert(p1[x] == p2[x]);
		}
	}

	cv::Mat matSave(width, width, CV_8UC3, mat1.data);
	cv::imwrite("E:/GitCode/OpenCV_Test/test_images/transpose_fbc.jpg", matSave);
	cv::imwrite("E:/GitCode/OpenCV_Test/test_images/transpose_cv.jpg", mat1_);

	cv::Mat matSrc1 = cv::imread("E:/GitCode/OpenCV_Test/test_images/1.jpg", 1);
	if (!matSrc1.data) {
		std::cout << "read image fail" << std::endl;
		return -1;
	}

	width = matSrc1.cols;
	height = matSrc1.rows;

	fbc::Mat_<uchar, 3> mat2(height, width, matSrc1.data);
	fbc::Mat_<uchar, 3> mat3(width, height);
	fbc::transpose(mat2, mat3);

	cv::Mat mat2_(height, width, CV_8UC3, matSrc1.data);
	cv::Mat mat3_;
	cv::transpose(mat2_, mat3_);

	assert(mat3.rows == mat3_.rows && mat3.cols == mat3_.cols && mat3.step == mat3_.step);
	for (int y = 0; y < mat3.rows; y++) {
		const fbc::uchar* p1 = mat3.ptr(y);
		const uchar* p2 = mat3_.ptr(y);

		for (int x = 0; x < mat3.step; x++) {
			assert(p1[x] == p2[x]);
		}
	}

	cv::Mat matSave1(width, height, CV_8UC3, mat3.data);
	cv::imwrite("E:/GitCode/OpenCV_Test/test_images/transpose1_fbc.jpg", matSave1);
	cv::imwrite("E:/GitCode/OpenCV_Test/test_images/transpose1_cv.jpg", mat3_);

	return 0;
}

int test_transpose_float()
{
	cv::Mat matSrc = cv::imread("E:/GitCode/OpenCV_Test/test_images/lena.png", 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;
	cv::Mat matSrc_;
	cv::resize(matSrc, matSrc_, cv::Size(width, width));

	fbc::Mat_<float, 1> mat1(width, width);
	memcpy(mat1.data, matSrc_.data, width * width * sizeof(float));
	fbc::transpose(mat1, mat1);

	cv::Mat mat1_(width, width, CV_32FC1);
	memcpy(mat1_.data, matSrc_.data, width * width * sizeof(float));
	cv::transpose(mat1_, mat1_);

	assert(mat1.rows == mat1_.rows && mat1.cols == mat1_.cols && mat1.step == mat1_.step);
	for (int y = 0; y < mat1.rows; y++) {
		const fbc::uchar* p1 = mat1.ptr(y);
		const uchar* p2 = mat1_.ptr(y);

		for (int x = 0; x < mat1.step; x++) {
			assert(p1[x] == p2[x]);
		}
	}

	cv::Mat matSrc1 = cv::imread("E:/GitCode/OpenCV_Test/test_images/1.jpg", 1);
	if (!matSrc1.data) {
		std::cout << "read image fail" << std::endl;
		return -1;
	}
	cv::cvtColor(matSrc1, matSrc1, CV_BGR2GRAY);
	matSrc1.convertTo(matSrc1, CV_32FC1);

	width = matSrc1.cols;
	height = matSrc1.rows;

	fbc::Mat_<float, 1> mat2(height, width, matSrc1.data);
	fbc::Mat_<float, 1> mat3(width, height);
	fbc::transpose(mat2, mat3);

	cv::Mat mat2_(height, width, CV_32FC1, matSrc1.data);
	cv::Mat mat3_;
	cv::transpose(mat2_, mat3_);

	assert(mat3.rows == mat3_.rows && mat3.cols == mat3_.cols && mat3.step == mat3_.step);
	for (int y = 0; y < mat3.rows; y++) {
		const fbc::uchar* p1 = mat3.ptr(y);
		const uchar* p2 = mat3_.ptr(y);

		for (int x = 0; x < mat3.step; x++) {
			assert(p1[x] == p2[x]);
		}
	}

	return 0;
}

GitHubhttps://github.com/fengbingchun/OpenCV_Test

OpenCV代码提取:transpose函数的实现的更多相关文章

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

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

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

    The Fourier Transform will decompose an image into its sinus and cosines components. In other words, ...

  3. OpenCV代码提取: threshold函数的实现

    threshold algorithm: The simplest image segmentation method. All thresholding algorithms take a sour ...

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

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

  5. OpenCV中的绘图函数-OpenCV步步精深

    OpenCV 中的绘图函数 画线 首先要为画的线创造出环境,就要生成一个空的黑底图像 img=np.zeros((512,512,3), np.uint8) 这是黑色的底,我们的画布,我把窗口名叫做i ...

  6. 基础学习笔记之opencv(24):imwrite函数的使用

    http://www.cnblogs.com/tornadomeet/archive/2012/12/26/2834336.html 前言 OpenCV中保存图片的函数在c++版本中变成了imwrit ...

  7. tf.transpose函数解析

    tf.transpose函数解析 觉得有用的话,欢迎一起讨论相互学习~Follow Me tf.transpose(a, perm = None, name = 'transpose') 解释 将a进 ...

  8. (转)Uri详解之——Uri结构与代码提取

    前言:依然没有前言…… 相关博客:1.<Uri详解之——Uri结构与代码提取>2.<Uri详解之二——通过自定义Uri外部启动APP与Notification启动> 上几篇给大 ...

  9. Uri详解之——Uri结构与代码提取

    目录(?)[+] 前言:依然没有前言…… 相关博客:1.<Uri详解之——Uri结构与代码提取>2.<Uri详解之二——通过自定义Uri外部启动APP与Notification启动& ...

随机推荐

  1. Haskell 与范畴论-函子、态射、函数

    范畴论基本概念 如果你是第一次听说范畴论(category theory),看到这高大上的名字估计心里就会一咯噔,到底数学威力巨大,光是高等数学就能让很多人噩梦连连.和搞编程的一样,数学家喜欢将问题不 ...

  2. TSP 模拟退火

    TSP——模拟退火解法 都知道TSP是经典的NP问题,从一个点开始遍历所有点,不重复,求最短路径. 可以用枚举终点,跑流量为2的最小费用,图论来做,时间复杂度为 ​ 费用流已经用到堆优化了.显然点,边 ...

  3. 程序的优化(PHP)

    有些小细节往往容易被人忽视.有时候常常说优化代码优化代码,但是实际操作的时候,最容易被忽视的如下所示: echo 比 print 快. 使用echo的多重参数代替字符串连接. 在执行for循环之前确定 ...

  4. idea + maven + webapp 项目搭建

    1.File-> New -> Project

  5. [转]这13个开源GIS软件,你了解几个?

    这些开源GIS软件,你了解几个?本文内容部分来源于一份罗列了关于GIS软件应用的文章,笔者将其编译整合. 地理信息系统(Geographic Information System,GIS)软件依赖于覆 ...

  6. 八数码(IDA*算法)

    八数码 IDA*就是迭代加深和A*估价的结合 在迭代加深的过程中,用估计函数剪枝优化 并以比较优秀的顺序进行扩展,保证最早搜到最优解 需要空间比较小,有时跑得比A*还要快 #include<io ...

  7. MFC通过URL下载并保存文件代码 转载

    http://blog.csdn.net/charlessimonyi/article/details/8666108?utm_source=tuicool&utm_medium=referr ...

  8. linux上安装Python3和django流程详解

    1.安装python3 1.1 安装相关依赖库(工具包)  --->很重要 yum install gcc patch libffi-devel python-devel zlib-devel ...

  9. 自动诊断档案库(ADR)学习

    (1)ADR概述 Oracle 11g的FDI(Fault Diagnosability Infrastructure)是自动化诊断方面的一个增强,其核心组件为自动诊断库(Automatic Diag ...

  10. java各种业务解决方案总结

    最近有点时间,突然感慨良多,感觉辛苦工作这么久什么都没有,总结了以前的工作,将接触的主要工具列出来,希望给大家解决问题做参考.相关工具都是实践检验过的 1.数据库 (1).内存数据库 redis (2 ...