1. 程式人生 > >C++程式設計常用程式碼

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);
}