Skip to content

Instantly share code, notes, and snippets.

@coder-ghw
Last active January 23, 2024 05:54
Show Gist options
  • Save coder-ghw/e2c4ebec16d4ff00293f88d881f32ab0 to your computer and use it in GitHub Desktop.
Save coder-ghw/e2c4ebec16d4ff00293f88d881f32ab0 to your computer and use it in GitHub Desktop.
c/c++
#ifndef __x_x_H__
#define __x_x_H__
#ifdef __cplusplus
extern "C"
{
#endif
class AlgFoo
{
public:
using Ptr = std::shared_ptr<AlgFoo>;
AlgFoo() {}
virtual ~AlgFoo(){}
static Ptr Create();
private:
};
/***************in cpp file : create()
AlgFoo::Ptr AlgFoo::Create()
{
std::shared_ptr<AlgFoo> alg_foo = std::make_shared<AlgFoo>();
return alg_foo;
}
*********************/
#ifdef __cplusplus
}
#endif
#endif
#include <fstream>
int main() {
std::ofstream outfile;
outfile.open("yourfile.txt", std::ios_base::app);//std::ios_base::app
outfile << "your data";
return 0;
}
#include <iostream>
#include <ctime>
using namespace std;
// Eigen 部分
#include <Eigen/Core>
// 稠密矩阵的代数运算(逆,特征值等)
#include <Eigen/Dense>
#define MATRIX_SIZE 50
/****************************
* 本程序演示了 Eigen 基本类型的使用
****************************/
int main( int argc, char** argv ) {
/********************************Eigen初始化**************************************/
// Eigen 以矩阵为基本数据单元。它是一个模板类。
// 它的前三个参数为:数据类型,行,列
// 声明一个 2*3 的 float 矩阵
Eigen::Matrix<float, 2, 3> matrix_23;
// 同时,Eigen 通过 typedef 提供了许多内置类型,不过底层仍是 Eigen::Matrix
// 例如 Vector3d 实质上是 Eigen::Matrix<double, 3, 1>
Eigen::Vector3d v_3d;
// 还有 Matrix3d 实质上是 Eigen::Matrix<double, 3, 3>
Eigen::Matrix3d matrix_33 = Eigen::Matrix3d::Zero(); //初始化为零
// 如果不确定矩阵大小,可以使用动态大小的矩阵
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > matrix_dynamic;
// 更简单的
Eigen::MatrixXd matrix_x;
// 这种类型还有很多,我们不一一列举
// 下面是对矩阵的操作
// 输入数据
matrix_23 << 1, 2, 3, 4, 5, 6;
// 输出
cout << matrix_23 << endl
/********************************Eigen index**************************************/
// 用()访问矩阵中的元素
for (int i=0; i<1; i++)
for (int j=0; j<2; j++)
cout<<matrix_23(i,j)<<endl;
v_3d << 3, 2, 1;
// 矩阵和向量相乘(实际上仍是矩阵和矩阵)
// 但是在这里你不能混合两种不同类型的矩阵,像这样是错的
// Eigen::Matrix<double, 2, 1> result_wrong_type = matrix_23 * v_3d;
/********************************Eigen 类型转化**************************************/
// 应该显式转换
Eigen::Matrix<double, 2, 1> result = matrix_23.cast<double>() * v_3d;
cout << result << endl;
// 同样你不能搞错矩阵的维度
// 试着取消下面的注释,看看会报什么错
// Eigen::Matrix<double, 2, 3> result_wrong_dimension = matrix_23.cast<double>() * v_3d;
/********************************Eigen 运算**************************************/
// 一些矩阵运算
// 四则运算就不演示了,直接用对应的运算符即可。
matrix_33 = Eigen::Matrix3d::Random();
cout << matrix_33 << endl << endl;
cout << matrix_33.transpose() << endl; //转置
cout << matrix_33.sum() << endl; //各元素和
cout << matrix_33.trace() << endl; //迹
cout << 10*matrix_33 << endl; //数乘
cout << matrix_33.inverse() << endl; //逆
cout << matrix_33.determinant() << endl; //行列式
// 特征值
// 实对称矩阵可以保证对角化成功
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigen_solver ( matrix_33.transpose()*matrix_33 );
cout << "Eigen values = " << eigen_solver.eigenvalues() << endl;
cout << "Eigen vectors = " << eigen_solver.eigenvectors() << endl;
// 解方程
// 我们求解 matrix_NN * x = v_Nd 这个方程
// N 的大小在前边的宏里定义,矩阵由随机数生成
// 直接求逆自然是最直接的,但是求逆运算量大
Eigen::Matrix< double, MATRIX_SIZE, MATRIX_SIZE > matrix_NN;
matrix_NN = Eigen::MatrixXd::Random( MATRIX_SIZE, MATRIX_SIZE );
Eigen::Matrix< double, MATRIX_SIZE, 1> v_Nd;
v_Nd = Eigen::MatrixXd::Random( MATRIX_SIZE,1 );
clock_t time_stt = clock(); // 计时
// 直接求逆
Eigen::Matrix<double,MATRIX_SIZE,1> x = matrix_NN.inverse()*v_Nd;
cout <<"time use in normal invers is " << 1000* (clock() - time_stt)/(double)CLOCKS_PER_SEC << "ms"
<< endl;
// 通常用矩阵分解来求,例如 QR 分解,速度会快很多
// 求解 matrix_NN * x = v_Nd 这个方程
time_stt = clock();
x = matrix_NN.colPivHouseholderQr().solve(v_Nd);
cout <<"time use in Qr compsition is " <<1000* (clock() - time_stt)/(double)CLOCKS_PER_SEC <<"ms"
<< endl;
return 0;
}
#include <Eigen/Core>
#include <Eigen/Geometry>
using namespace Eigen;
void test_geometry() {
// Eigen/Geometry 模块提供了各种旋转和平移的表示
// 3D 旋转矩阵直接使用 Matrix3d 或 Matrix3f
Matrix3d rotation_matrix = Matrix3d::Identity();
// 旋转向量使用 AngleAxis, 它底层不直接是Matrix,但运算可以当作矩阵(因为重载了运算符)
AngleAxisd rotation_vector(M_PI / 4, Vector3d(0, 0, 1)); //沿 Z 轴旋转 45 度
cout.precision(3);
cout << "rotation matrix =\n" << rotation_vector.matrix() << endl; //用matrix()转换成矩阵
// 也可以直接赋值
rotation_matrix = rotation_vector.toRotationMatrix();
// 用 AngleAxis 可以进行坐标变换
Vector3d v(1, 0, 0);
Vector3d v_rotated = rotation_vector * v;
cout << "(1,0,0) after rotation (by angle axis) = " << v_rotated.transpose() << endl;
// 或者用旋转矩阵
v_rotated = rotation_matrix * v;
cout << "(1,0,0) after rotation (by matrix) = " << v_rotated.transpose() << endl;
// 欧拉角: 可以将旋转矩阵直接转换成欧拉角
Vector3d euler_angles = rotation_matrix.eulerAngles(2, 1, 0); // ZYX顺序,即yaw-pitch-roll顺序
cout << "yaw pitch roll = " << euler_angles.transpose() << endl;
// 欧氏变换矩阵使用 Eigen::Isometry
Isometry3d T = Isometry3d::Identity(); // 虽然称为3d,实质上是4*4的矩阵
T.rotate(rotation_vector); // 按照rotation_vector进行旋转
T.pretranslate(Vector3d(1, 3, 4)); // 把平移向量设成(1,3,4)
cout << "Transform matrix = \n" << T.matrix() << endl;
// 用变换矩阵进行坐标变换
Vector3d v_transformed = T * v; // 相当于R*v+t
cout << "v tranformed = " << v_transformed.transpose() << endl;
// 对于仿射和射影变换,使用 Eigen::Affine3d 和 Eigen::Projective3d 即可,略
// 四元数
// 可以直接把AngleAxis赋值给四元数,反之亦然
Quaterniond q = Quaterniond(rotation_vector);
cout << "quaternion from rotation vector = " << q.coeffs().transpose()
<< endl; // 请注意coeffs的顺序是(x,y,z,w),w为实部,前三者为虚部
// 也可以把旋转矩阵赋给它
q = Quaterniond(rotation_matrix);
cout << "quaternion from rotation matrix = " << q.coeffs().transpose() << endl;
// 使用四元数旋转一个向量,使用重载的乘法即可
v_rotated = q * v; // 注意数学上是qvq^{-1}
cout << "(1,0,0) after rotation = " << v_rotated.transpose() << endl;
// 用常规向量乘法表示,则应该如下计算
cout << "should be equal to " << (q * Quaterniond(0, 1, 0, 0) * q.inverse()).coeffs().transpose() << endl;
}
#include <boost/filesystem.hpp>
#include <string>
#include <iostream>
#include <sstream>
int createPathUseFileName()
{
std::string file_in_speckle(file_img);
std::string file_in_flagged;
std::string path_result;
std::string base_filename = file_in_speckle.substr(file_in_speckle.find_last_of("/\\") + 1);
std::string::size_type const p(base_filename.find_last_of('.'));
std::string file_without_extension = base_filename.substr(0, p);
path_result = cv::format("%s/%s", TRACE_DIR, file_without_extension.c_str());
if (!boost::filesystem::exists(path_result))
boost::filesystem::create_directories(path_result);
return 0;
}
auto splitString(const std::string& input, char delimiter) {
std::vector<std::string> result;
std::string token;
std::istringstream tokenStream(input);
while (std::getline(tokenStream, token, delimiter)) {
result.push_back(token);
}
return result;
}
auto SplitAndSort(std::vector<std::string>& fnames,
const std::string& pattern) {
std::vector<std::string> fnames_filter;
// filter
for (auto& fname : fnames) {
auto splitnames = splitString(fname, '_');
auto capture_type = splitnames[2];
if (std::stoi(capture_type) == 10)
fnames_filter.emplace_back(fname);
}
// Sort
std::sort(
fnames_filter.begin(),
fnames_filter.end(),
[](const std::string& a, const std::string& b) { return GetFrameId0(a) < GetFrameId0(b); });
return fnames_filter;
}
auto FilterAndSort(std::vector<std::string>& fnames,
const std::string& pattern) {
std::vector<std::string> fnames_filter;
// filter
boost::regex reg(pattern);
for (auto& fname : fnames) {
if (!boost::regex_search(fname, reg)) {
continue;
}
fnames_filter.emplace_back(fname);
}
// Sort
std::sort(fnames_filter.begin(),
fnames_filter.end(),
[](const std::string& a, const std::string& b) {
return std::atoi(GetFrameId(a).c_str()) < std::atoi(GetFrameId(b).c_str());
});
return fnames_filter;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment