(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