分别用Eigen和C++(OpenCV)实现图像(矩阵)转置

(1)、标量(scalar):一个标量就是一个单独的数。

(2)、向量(vector):一个向量是一列数,这些数是有序排列的,通过次序中的索引,可以确定每个单独的数。

(3)、矩阵(matrix):矩阵是一个二维数组,其中的每一个元素被两个索引而非一个所确定。

(4)、张量(tensor):在某些情况下,我们会讨论坐标超过两维的数组。一般地,一个数组中的元素分布在若干维坐标的规则网格中,我们将其称之为张量。

(5)、转置(transpose):矩阵的转置是以对角线为轴的镜像,这条从左上角到右下角的对角线被称为主对角线(main diagonal):

(AT)i,j = Aj,i

向量可以看作是只有一列的矩阵。对应地,向量的转置可以看作是只有一行的矩阵。有时,我们通过将向量元素作为行矩阵写在文本行中,然后使用转置操作将其变为标准的列向量,来定义一个向量。

标量可以看作是只有一个元素的矩阵。因此,标量的转置等于它本身。

以上内容摘自:《深度学习中文版》(https://github.com/exacity/deeplearningbook-chinese)

下面是用C+++OpenCVC实现的图像转置:

#include "funset.hpp"
#include <iostream>
#include <string>
#include <vector>
#include <opencv2/opencv.hpp>

int test_mat_transpose()
{
	const std::vector<std::string> image_name{ "E:/GitCode/NN_Test/data/images/test1.jpg",
		"E:/GitCode/NN_Test/data/images/ret_mat_transpose.jpg"};
	cv::Mat mat_src = cv::imread(image_name[0]);
	if (!mat_src.data) {
		fprintf(stderr, "read image fail: %s\n", image_name[0].c_str());
		return -1;
	}

	cv::Mat mat_dst(mat_src.cols, mat_src.rows, mat_src.type());

	for (int h = 0; h < mat_dst.rows; ++h) {
		for (int w = 0; w < mat_dst.cols; ++w) {
			const cv::Vec3b& s = mat_src.at<cv::Vec3b>(w, h);
			cv::Vec3b& d = mat_dst.at<cv::Vec3b>(h, w);
			d = s;
		}
	}

	cv::imwrite(image_name[1], mat_dst);

	return 0;
}
下面是用Eigen实现的图像转置:

#include "funset.hpp"
#include <iostream>
#include <vector>
#include <string>
#include <opencv2/opencv.hpp>
#include <Eigen/Dense>

int test_mat_transpose()
{
	const std::vector<std::string> image_name{ "E:/GitCode/Eigen_Test/test_data/test1.jpg",
		"E:/GitCode/Eigen_Test/test_data/ret_mat_transpose.jpg" };
	cv::Mat mat_src = cv::imread(image_name[0]);
	if (!mat_src.data) {
		fprintf(stderr, "read image fail: %s\n", image_name[0].c_str());
		return -1;
	}

	std::vector<cv::Mat> mat_split;
	cv::split(mat_src, mat_split);

	// reference: http://stackoverflow.com/questions/14783329/opencv-cvmat-and-eigenmatrix
	// Map the OpenCV matrix with Eigen:
	Eigen::Map<Eigen::Matrix<unsigned char, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>
		map_b(mat_split[0].data, mat_split[0].rows, mat_split[0].cols),
		map_g(mat_split[1].data, mat_split[1].rows, mat_split[1].cols),
		map_r(mat_split[2].data, mat_split[2].rows, mat_split[2].cols);

	Eigen::Matrix<unsigned char, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>
		trans_b = map_b.transpose(),
		trans_g = map_g.transpose(),
		trans_r = map_r.transpose();

	cv::Mat
		mat_dst_b(trans_b.rows(), trans_b.cols(), CV_8UC1, trans_b.data()),
		mat_dst_g(trans_g.rows(), trans_g.cols(), CV_8UC1, trans_g.data()),
		mat_dst_r(trans_r.rows(), trans_r.cols(), CV_8UC1, trans_r.data());
	std::vector<cv::Mat> mat_merge;
	mat_merge.push_back(std::move(mat_dst_b));
	mat_merge.push_back(std::move(mat_dst_g));
	mat_merge.push_back(std::move(mat_dst_r));
	cv::Mat mat_dst;
	cv::merge(mat_merge, mat_dst);

	cv::imwrite(image_name[1], mat_dst);

	return 0;
}
经测试两种方法实现的结果是一致的,原图如下:

结果如下:


GitHub

https://github.com/fengbingchun/NN_Test
https://github.com/fengbingchun/Eigen_Test

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值