C++编程常用代码

计时:

#include<chrono>
chrono::steady_clock::time_point t1=chrono::steady_clock::now();
//do something
chrono::steady_clock::time_point t2=chrono::steady_clock::now();
chrono::duration<double> time_used=chrono::duration_cast<chrono::duration<double>>(t2-t1);

double time0=static_cast<double>(getTickCount());
//do something
time0=((double)getTickCount()-time0)/getTickFrequency();

随机数生成:

DUtils::Random::RandomInt(0,n);//随机生成0~n间的整数

编程习惯:

//用宏定义(不要写死)
#define IMG_WIDTH 640
#define IMG_HIGHT 480

//调试宏
#define DEBUG
#ifdef DEBUG
//do something
#endif

//注释代码块
#if 0
//do something
#endif

//函数入口进行参数检查
assert(条件/表达式);

遵循doxygen注释规范

浮点定点化
(float*2^n)>>n

for循环并行处理:
包含OpenMP的头文件:#include<omp.h>
在for循环前面加上一行:#pragma omp parallel for

Log日志:

数学常用

atan2(y,x);//弧度

使用单例模型来进行不同文件间的变量传递:

//a.h文件
//为了避免同一个文件被include多次,C/C++中有两种方式,一种是#ifndef方式,一种是#pragma once方式
#pragma once
#ifndef _A_H_
#define _A_H_

class Singleton 
{
public:
    Singleton(){};
    static Singleton* instance;

    static Singleton* get_instance()
    {
        if (instance == null) 
        {
            instance = new Singleton();
        }
        return instance;
    }

    int b;
    void set_b(int c){b=c;}
    int get_b(){return b;]
}
#endif

//1.cpp
#include "a.h"
Singleton *ptr=Singleton::get_instance();
ptr->set_b(c);

//2.cpp
#include "a.h"
Singleton *ptr=Singleton::get_instance();
int d=ptr->get_b();

opencv常用

opencv默认用CV_64F(double)类型,为了减少不必要的转换,尽量使用double型

cvRound(5.5);//返回跟参数最接近的整数值(四舍五入)
cvFloor(5.9) 返回不大于参数的最大整数值
cvCeil(5.1);// 返回不小于参数的最小整数值
cv::reduce(_input_mat,_result_mat,1,CV_REDUCE_SUM);//将输入的矩阵按行/列形式进行特定操作
cv::pow(_src_mat,_n,_dst_mat);//将矩阵的每个元素n次方
cv::eigen(_symmetry_mat,_eigenvalues,_eigenvectors);//计算对称矩阵的特征值和特征向量

旋转矩阵近似:

Mat r;//近似旋转矩阵,行列式接近1
Vec3d tmp;
Mat rotation;
Rodrigues(r,tmp);//罗德里格斯公式(旋转矩阵与旋转向量转换)
Rodrigues(tmp,rotation);

 SVD解线性方程:

(a)解齐次线性方程AX=0
Mat w,u,vt;
cv::SVDecomp(A,w,u,vt,cv::SVD::MODIFY_A|cv::SVD::FULL_UV);//u*w*vt*x=0
x=vt.row(最后一行);//A`A最小特征值对应的特征向量

(b)解非齐次线性方程AX=b
Mat w,u,vt;
cv::SVDecomp(A,w,u,vt,cv::SVD::MODIFY_A|cv::SVD::FULL_UV);//u*w*vt*x=b
Mat w_inv=Mat::diag(w);
for(int i=0;i<3;i++)
{
    w_inv.at<double>(i)=1./w_inv.at<double>(i);
}
x=vt.t()*w_inv*u.t()*b;

Mat类常用: 

Mat mat,mat2;
mat::create(_rows,_cols,_type);
mat.t();//转置
mat.inv();//求逆
mat.clone();//拷贝
mat.row(n);//第n行
mat.reshape(0,3);//单通道,3行(9x1->3x3)
mat.type();//CV_32F(float)为5,CV_64F(double)为6
mat.convertTo(mat2,CV_32F);
determinant(mat);//行列式

Mat R=Mat::eye(3,3,CV_32F);
Mat t=Mat::zeros(3,1,CV_32F);
Mat T=Mat::eye(4,4,CV_32F);
R.copyTo(T.rowRange(0,3).colRange(0,3));
t.copyTo(T.rowRange(0,3).col(3));

Eigen常用

#include<Eigen/Eigen>
Eigen::Vector3f vec(1,1,0),vec2;//列向量
vec2<<2,0,2;
vec[2]=1;
vec.x();//第一个分量
vec.norm();//模长
vec.normalized();//单位向量
vec.dot(vec2);//点乘
vec.cross(vec2);//叉乘

Eigen::Matrix<float,4,4> T;
T.transpose();//转置
T.inverse();//逆
T.setZero();
T.block<3,3>(0,0);
T.topLeftCorner(3, 3);
T.topRightCorner(3, 1);

Mat rotation_mat;
//旋转矩阵
Eigen::Matrix3f rotation_matrix3f=toMatrix3f(rotation_mat);
//欧拉角
Eigen::Vector3f euler_angles=rotation_matrix3f.eulerAngles(0,1,2);//XYZ顺序(pitch/yaw/roll)
cout<<"euler_angles: "<<euler_angles*180/CV_PI<<endl;
//旋转向量(轴角)
Eigen::AngleAxisf rotation_vector(CV_PI/4,Eigen::Vector3f(0,1,0));//绕y轴顺时针旋转45度(转yaw)
rotation_vector.fromRotationMatrix(rotation_matrix3f);
cout<<"axi: "<<rotation_vector.axis()<<" angle: "<<rotation_vector.angle()*180/CV_PI<<endl;
rotation_matrix3f=rotation_vector.toRotationMatrix();

cv::Mat和Eigen::Matrix相互转换

Eigen::Matrix<float,3,3> toMatrix3f(const cv::Mat &cvMat3)
{
    Eigen::Matrix<float,3,3> M;
    M << cvMat3.at<float>(0,0),cvMat3.at<float>(0,1),cvMat3.at<float>(0,2),
         cvMat3.at<float>(1,0),cvMat3.at<float>(1,1),cvMat3.at<float>(1,2),
         cvMat3.at<float>(2,0),cvMat3.at<float>(2,1),cvMat3.at<float>(2,2),
    return M;
}

Mat toCvMat(const Eigen::Matrix3f &m)
{
    cv::Mat cvMat(3,3,CV_32F);
    for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
            cvMat.at<float>(i,j)=m(i,j);
    return cvMat.clone();
}

特征点提取匹配

//FAST特征提取
Mat img;
vector<KeyPoint> keypoints;
FAST(img,keypoints,60);
vector<Point2f> points;
for(auto kp:keypoints)
{
    points.push_back(kp.pt);
}

//光流跟踪
vector<Point2f> keypoints1(给定),keypoints2(待求)
vector<unsigned char> status;
vector<float> error;
calcOpticalFlowPyrLK(img1,img2,keypoints1,keypoints2,status,error,Size(21,21),3);

//ORB特征提取
Mat img1,img2;
Ptr<ORB> orb=ORB::create(500);
vector<KeyPoint> keypoint1,keypoint2;
Mat descriptor1,descriptor2;
orb->detecAndCompute(img1,Mat(),keypoint1,descriptor1);
orb->detecAndCompute(img2,Mat(),keypoint2,descriptor2);

//暴力匹配
BFMatcher matcher;
vector<DMatch> matches;
matcher.match(descriptor1,descriptor2,matches);

//计算单应矩阵
vector<Point2f> vp1,vp2;
Mat H=findHomography(vp1,vp2);
//分解单应矩阵
vector<Mat> vR,vt,vn;
Mat k=(Mat_<float>(3,3)<<fx,0,cx,0,fy,cy,0,0,1);
int num=decomposeHomographyMat(H,k,vR,vt,vn);

//画出特征点提取和匹配
void draw_keypoints(Mat first_frame,Mat second_frame,vector<Point2f> first_keypoints,vector<Point2f> second_keypoints,vector<unsigned char> status)
{
    if(first_frame.type()==CV_8UC1)
    {
        cvtColor(first_frame,first_frame,CV_GRAY2BGR);
    }
    if(second_frame.type()==CV_8UC1)
    {
        cvtColor(second_frame,second_frame,CV_GRAY2BGR);
    }
    Mat img_show(first_frame.rows,first_frame.cols*2,CV_8UC3);
    first_frame.copyTo(img_show(Rect(0,0,first_frame.rows,first_frame.cols)));
    second_frame.copyTo(img_show(Rect(first_frame.cols,0,second_frame.rows,second_frame.cols)));
    for(int i=0;i<first_keypoints.size();i++)
    {
        if(!status[i]) continue;
        float b=255*float(rand())/RAND_MAX;
        float g=255*float(rand())/RAND_MAX;
        float r=255*float(rand())/RAND_MAX;
        circle(img_show,first_keypoints[i],4,Scalar(b,g,r),1);
        circle(img_show,second_keypoints[i].x+first_frame.cols,second_keypoints[i].y,4,Scalar(b,g,r),1);
        line(img_show,first_keypoints[i],Point2f(second_keypoints[i].x+first_frame.cols,second_keypoints[i].y),Scalar(b,g,r),1);
    }
    imshow("match",img_show);
    waitKey(1);

    Mat img_show2(second_frame.rows,second_frame.cols,CV_8UC3);
    second_frame.copyTo(img_show2);
    for(int i=0;i<first_keypoints.size();i++)
    {
        if(!status[i]) continue;
        circle(img_show2,second_keypoints[i],2,Scalar(0,0,255),-1);
        line(img_show2,first_keypoints[i],second_keypoints[i],Scalar(255,255,255),1);
    }
    imshow("match",img_show);
    waitKey(1);
}

猜你喜欢

转载自blog.csdn.net/A_L_A_N/article/details/82756143