OpenCV中的transpose函数实现图像转置,公式为:
目前fbc_cv库中也实现了transpose函数,支持多通道,uchar和float两种数据类型,经测试,与OpenCV3.1结果完全一致。
实现代码transpose.hpp:
- // fbc_cv是免费软件,并且使用与OpenCV相同的许可证
- #ifndef FBC_CV_TRANSPOSE_HPP_
- #define FBC_CV_TRANSPOSE_HPP_
- /* 参考: include/opencv2/core.hpp
- modules/core/src/matrix.cpp
- */
- #include <typeinfo>
- #include "core/mat.hpp"
- namespace fbc {
- // 转置矩阵
- // \f[\texttt{dst} (i,j) = \texttt{src} (j,i)\f]
- // 支持类型:uchar/float,多通道
- 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;
- }
- // 处理存储在STL向量中的单列/单行矩阵的情况.
- 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;
- }
- } // 命名空间fbc
- #endif // FBC_CV_TRANSPOSE_HPP_