C++程式設計常用程式碼
阿新 • • 發佈:2018-11-08
計時:
#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);
}