C++ Eigen库
1.Eigen
序号 | 功能 | 例子 |
---|---|---|
1 | 赋值 | Eigen::MatrixXf mat (12,1);
\\%
mat << 1, 2, 3, 4,5,6,7,8,9,10,11,12; |
2 | Inplace操作 \\% resize | mat.resize(4, 3);
\\%
1 5 9
\\%
2 6 10
\\%
3 7 11
\\%
4 8 12 |
3 | 转置 \\% transposeInPlace | mat.transposeInPlace();
\\%
1 2 3 4
\\%
5 6 7 8
\\%
9 10 11 12 |
4 | 切片 | mat.block(1,2,2,2)
\\%
7 8
\\%
11 12
\\%
mat.leftCols(2)
\\%
1 2
\\%
5 6
\\%
9 10
\\%
mat.middleCols(1,2)
\\%
2 3
\\%
6 7
\\%
10 11
\\%
mat.rightCols(2)
\\%
3 4
\\%
7 8
\\%
11 12
\\%
另有 topRows bottomRows middleRows |
5 | c++array类型 \\% 转eigen数组 | int arr[12] = { 1, 2, 3, 4,5,6,7,8,9,10,11,12 };
\\%
Eigen::MatrixXi mat(12, 1);
\\%
mat = Eigen::Map<Eigen::MatrixXi>(arr,12,1);
\\%
第一个输入是指针类型,就可以实现转换 |
6 | eigen内部类型转换 | Eigen::MatrixXf matF(12, 1);
\\%
matF=mat.cast<float>(); |
7 | eigen类型转c++ vector | auto vec=std::vector<float>(matF.data(), matF.data() + 12);
\\%
1 2 3 4 5 6 7 8 9 10 11 12
\\%
|
8 | c++vector类型 \\% 转eigen数组 | matF = Eigen::Map<Eigen::MatrixXf>(vec.data(),3,4)
\\%
1 4 7 10
\\%
2 5 8 11
\\%
3 6 9 12
\\%
|
9 | eigen数组转c++指针 | float* pt = matF.data();
\\%
for (int i = 0; i < 12; i++) cout << *(pt++) << " ";
\\%
\\%
1 2 3 4 5 6 7 8 9 10 11 12
\\%
|
10 | 拷贝 | Eigen::MatrixXf matF(2, 3);
\\%
matF << 1, 2, 3, 4, 5,6;
\\%
\\%
1 2 3
\\%
4 5 6
\\%
auto matF_rep = matF.replicate(2,2);
\\%
\\%
1 2 3 1 2 3
\\%
4 5 6 4 5 6
\\%
1 2 3 1 2 3
\\%
4 5 6 4 5 6 |
11 | 判断两个矩阵是否相等 | Eigen::MatrixXf matF1(2, 3);
\\%
matF1 << 0,1, 2, 3, 4, 5;
\\%
0 1 2
\\%
3 4 5
\\%
\\%
Eigen::MatrixXf matF2(2, 3);
\\%
matF2 << 0,1.1, 2, 3, 4, 5;
\\%
\\%
0 1.1 2
\\%
3 4 5
\\%
auto eq = matF1.cwiseEqual(matF2);
\\%
\\%
1 0 1
\\%
1 1 1
\\%
bool eq2 = matF1.isApprox(matF2);
\\%
0
\\%
通过L2 norm来判断
\\%
(matF1 - matF2).norm()
\\%
0.1 |
12 | 运算 | Eigen::MatrixXf matF(2, 3);
\\%
matF << 1, 2, 3, 4, 5,6;
\\%
\\%
1 2 3
\\%
4 5 6
\\%
matF = (matF.array() - 1).matrix();
\\%
\\%
0 1 2
\\%
3 4 5 |
2.opencv
序号 | 功能 | 例子 |
---|---|---|
1 | 赋值 | unsigned short m[4][4] ={ {1, 2, 3,4}, {5, 6,7,8},{ 9,10,11,12}, { 13,14,15,16}};
\\%
cv::Mat cvMat(4, 4, CV_16UC1, m);
\\%
[1, 2, 3, 4;
\\%
5, 6, 7, 8;
\\%
9, 10, 11, 12;
\\%
13, 14, 15, 16] |
2 | 数据类型转换 | cvMat.convertTo(cvMat, CV_8UC1); |
3 | 翻转 | cv::flip(cvMat, cvMat, 0) ;
\\%
[13, 14, 15, 16;
\\%
9, 10, 11, 12;
\\%
5, 6, 7, 8;
\\%
1, 2, 3, 4] |
4 | 切片 | cv::Mat subMat = cvMat(cv::Rect(2,1, 2, 2));
\\%
[7, 8;
\\%
11, 12]
\\%
cvMat.colRange(0,2)
\\%
[1, 2;
\\%
5, 6;
\\%
9, 10;
\\%
13, 14]
\\%
cvMat.rowRange(1,3)
\\%
[5, 6, 7, 8;
\\%
9, 10, 11, 12] |
5 | 获取数据类型 | cvMat.type()
\\%
0 |
6 | 获取像素值 | cvMat.at<uint16_t>(1,1)
\\%
6
\\%
cvMat2.at<uchar>(i,j)
\\%
cvMat2.at<float>(i,j) |
7 | Mat数组转c++指针 \\% Mat数组转c++ vector | uint16_t* p = cvMat.ptr< uint16_t>(0);
\\%
std::vector<unsigned short> vec(cvMat.reshape(0, 1)); |
8 | merge | int w, h;
\\%
std::vector <cv::Mat> img(3);;
\\%
img.at(0) = cv::Mat::zeros(cv::Size(w, h), CV_8UC1);
\\%
img.at(1) = cv::Mat::zeros(cv::Size(w, h), CV_8UC1);
\\%
img.at(2) = cv::Mat::zeros(cv::Size(w, h), CV_8UC1);
\\%
cv::Mat img2;
\\%
cv::merge(img, img2); |
9 | 运算 | 求逆 (针对float/double类型)
\\%
cv::Mat cvMat_inv;
\\%
cv::invert(cvMat, cvMat_inv); |
10 | 交换两行 | 方法一
\\%
auto rowMat = a.row(0).clone();
\\%
a.row(1).copyTo(a.row(0));
\\%
rowMat.copyTo(a.row(1));
\\%
方法二
\\%
auto rowMat = a.row(0).clone();
\\%
a.row(0) = a.row(1) + 0;
\\%
a.row(1) =rowMat.clone() + 0;
\\%
[ 4, 5, 6;
\\%
1, 2, 3] |
11 | mask | unsigned char ls[]{ 1,2,3,4,5,6 }; \\% cv::Mat a(2,3, CV_8UC1, ls); \\% std::cout << a << std::endl; \\% [ 1, 2, 3; \\% 4, 5, 6] \\% unsigned char ls2[]{ 0,0,255,255,0,255 }; \\% cv::Mat mask(2, 3,CV_8UC1, ls2); \\% cv::bitwise_and(a, mask, a); \\% std::cout << a << std::endl; \\% [[ 0, 0, 3; \\% 4, 0, 6] |
12 | c++/opencv \\% 数据类型对应 | unsigned char —— CV_8U \\% int —— CV_32S \\% float —— CV_32F \\% double——CV_64F; |
13 | 获取Mat最大最小值以及索引 | double minVal, maxVal;
\\%
cv::Point minId, maxId;
\\%
cv::minMaxLoc(a.row(1).clone(), &minVal, &maxVal, &minId, &maxId); |
14 | reduce 运算
\\%
REDUCE_SUM
\\%
REDUCE_AVG
\\%
REDUCE_MAX
\\%
REDUCE_MIN
\\%
REDUCE_SUM2 | 按列求和 (使用的时候注意数据类型)
\\%
尝试了下,返回类型设置为CV_32F/CV_64F一般没问题
\\%
float ls[6]{ 0,1,2,3,4,5};
\\%
cv::Mat res(2,3, CV_32FC1, ls);
\\%
cv::Mat res2;
\\%
cv::reduce(res, res2,0, cv::REDUCE_SUM,CV_32FC1);
\\%
[3, 5, 7]
\\%
按行计算将reduce中0改为1 |
15 | 非极大值抑制 nms | bboxes.push_back(cv::Rect(j,i ,w,h ));
\\%
...
\\%
cv::dnn::NMSBoxes(bboxes, scores, match_thresh, nms_thresh, indices; |
16 | 阈值设置 | 低于某个值的所有数设置为0
\\%
double thresholdValue = 40;
\\%
cv::threshold(mat, mat, thresholdValue, 0, cv::THRESH_TOZERO);
\\%
高于某个值的所有数设置为0
\\%
double thresholdValue = 40;
\\%
cv::threshold(mat, mat, thresholdValue, 0, cv::THRESH_TOZERO_INV); |
17 | 定义颜色 | cv::Scalar(255, 0, 0);
\\%
直接用括号括起来不对 |
18 | vector转mat | std::vector<cv::Vec3b> vec =...
\\%
cv::Mat mat(vec.size(), 1, CV_8UC3, vec.data()); |
19 | 切片复制到另外一个mat | a.copyTo(B(cv::Rect(y, x, w,h));
\\%
将B矩阵中的一部分替换为a |
第12项完整的数据类型对应关系如下(参考 5):
3.filesystem
这里介绍的是std::experimental::filesystem::v1
。
注意:c++17直接使用std::filesystem
,方法大致相同。
序号 | 功能 | 例子 |
---|---|---|
1 | 字符串转path | string path = "E:/tem/tmp2/tmp3.txt";
\\%
auto filePath = fs::path(path);
\\%
cout << typeid(filePath).name() << endl;
\\%
//class std::experimental::filesystem::v1::path |
2 | path转字符串 | cout << filePath.string() << endl;
\\%
//E:\tem\tmp2\tmp3.txt |
3 | 获取文件名basename | cout << filePath.filename().string();
\\%
//tmp3.txt |
4 | 获取不带后缀的文件名 | cout << filePath.stem().string();
\\%
//tmp3 |
5 | 获取文件后缀名 | cout << filePath.extension().string();
\\%
//.txt |
6 | 后缀名转小写 | string ext = filePath.extension().string();
\\%
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
\\%
cout << ext << endl;
\\%
//.txt |
7 | 父目录 | cout <<filePath.parent_path().string();
\\%
//E:\tem\tmp2 |
8 | is_directory | cout<< "is_directory: " <<fs::is_directory(filePath);
\\%
//is_directory: 0 |
9 | is_regular_file | cout << "is_regular_file: "<<fs::is_regular_file(filePath);
\\%
//is_regular_file: 1 |
10 | is_exists | cout << "is_exists: " <<fs::exists(filePath);
\\%
//is_exists: 1 |
11 | 创建单级、多级目录 | bool okey=fs::create_directory("E:/1");
\\%
fs::create_directories("E:/1/2/3/4"); |
12 | 删除文件/文件夹 | fs::remove(filePath);//删除单个文件
\\%
fs::remove_all(filePath.parent_path());//删除单个文件或者文件夹及其下的所有文件 |
参考文献
[1] c++ - 在 Eigen::Matrix::data() 上使用 std::move 将 Eigen::Matrix 转换为 vector
[2] C+±数组-vector:.data()函数
[3] cv::Mat Class Reference
[4] OpenCV reduce 函数
[5] https://docs.opencv.org/3.4/d3/d63/classcv_1_1Mat.html#aa5d20fc86d41d59e4d71ae93daee9726