robomaster视觉组代码中的一些函数
看到的一些代碼,看到不少陌生的函數。記錄一點之前沒怎么用過的c++的用法。
explicit operator bool() const { return state; }
int operator()(const cv::Mat &image);
顯式的類型轉換運算符(explicit)
SmallInt si;
si = 4; //首先將4隱式轉換為SmallInt,然后調用SmallInt::operator=
cout << si + 3 << endl; //打印7。首先將si隱式地轉換為int,然后執(zhí)行整數的加法。如果不定義operator,那么這一步將出錯
fmax()函數是cmath標頭的庫函數,用于查找給定數字的最大值,它接受兩個數字并返回較大的一個。
Syntax of fmax() function:
fmax()函數的語法:
fmax(x, y);RotatedRect該類表示平面上的旋轉矩形,有三個屬性:
矩形中心點(質心) 邊長(長和寬) 旋轉角度 class CV_EXPORTS RotatedRect { public://構造函數RotatedRect();RotatedRect(const Point2f& center, const Size2f& size, float angle);RotatedRect(const CvBox2D& box);void points(Point2f pts[]) const;//!返回矩形的4個頂點Rect boundingRect() const; //返回包含旋轉矩形的最小矩形operator CvBox2D() const; //!轉換到舊式的cvbox2d結構Point2f center; //矩形的質心Size2f size; //矩形的邊長float angle; //旋轉角度,當角度為0、90、180、270等時,矩形就成了一個直立的矩形 }; std::vector<cv::Mat> channels; // 通道拆分cv::split(src, channels); /************************/if (enemy_color == ENEMY_BLUE) { /* */color_channel = channels[0]; /* 根據目標顏色進行通道提取 */} else if (enemy_color == ENEMY_RED) { /* */color_channel = channels[2]; /************************/}int light_threshold;if(enemy_color == ENEMY_BLUE){light_threshold = 225;}else{light_threshold = 200;}常使用push_back()向容器中加入一個右值元素(臨時對象)時,首先會調用構造函數構造這個臨時對象,然后需要調用拷貝構造函數將這個臨時對象放入容器中。原來的臨時變量釋放。這樣造成的問題就是臨時變量申請資源的浪費。
引入了右值引用,轉移構造函數后,push_back()右值時就會調用構造函數和轉移構造函數,如果可以在插入的時候直接構造,就只需要構造一次即可。這就是c++11 新加的emplace_back
void cv::split(
const cv::Mat& mtx, //輸入圖像
vector& mv // 輸出的多通道序列(n個單通道序列)
);
opencv imdecode和imencode用法
主要是對內存數據自動編解碼
string fname = "D:/image.jpg"; //! 以二進制流方式讀取圖片到內存 FILE* pFile = fopen(fname.c_str(), "rb"); fseek(pFile, 0, SEEK_END); long lSize = ftell(pFile); rewind(pFile); char* pData = new char[lSize]; fread(pData, sizeof(char), lSize, pFile); fclose(pFile);//! 解碼內存數據,變成cv::Mat數據 cv::Mat img_decode; vector<uchar> data; for (int i = 0; i < lSize; ++i){data.push_back(pData[i]); } img_decode = cv::imdecode(data, CV_LOAD_IMAGE_COLOR);轉載一個程序:原文鏈接:https://blog.csdn.net/tt_ren/article/details/53227900
程序首先讀入一個圖片。然后encode,之后把encode后的內容寫入文件(實際應用可以發(fā)送到網絡)。
第二步,從文件讀取encode的內容。然后解碼decode。轉換為mat格式,顯示出來。
imencode(".png", img_encode, data_encode); 第一個參數是圖片后綴,第二個:Mat類型,第三個:vector類型 應該意為把Mat編碼為向量。
注意兩個函數的參數數量。imdecode有兩個參數,encode有三個
注意這個寫法:
std::vector data(str_tmp.begin(), str_tmp.end()); 直接把字符串轉化為一組unchar類型的向量。
相機標定部分:
// // StereoCalib.h // stereo_calibrate_toe // // Created by ding on 17/8/17. // Copyright (c) 2017年 ding. All rights reserved. //#ifndef __stereo_calibrate_toe__StereoCalib__ #define __stereo_calibrate_toe__StereoCalib__#include "Header.h"typedef struct{int height;int width;float distance_const;float f;//float yparam_const;//float ground;//float init_z;float lightbase; }CalibParam;class StereoCalib{ public:StereoCalib(const string &path){filehead = path;this->zpos = 0;this->ypos = 0;this->xpos = 0;};void KeyParam(int key);void Process(Mat &left,Mat &right); private:void distanceCalib();void X_calib();void Y_calib();void FindTarget();void Position_show();void center_g(const vector<Point> contour,Point ¢er);void OtherOption(); public:Mat thresleft_cp,thresright_cp; private:int rows,cols;int key;int calib_process = 0;int VisionDis = 0;vector<vector<Point> > contours_left,contours_right,Triangle_left,Triangle_right;vector<Vec4i> hierarchy_L,hierarchy_R;vector<Point> approx_left,approx_right;Point left_center,right_center;vector<Mat> split_left,split_right;Mat left_diff[2],right_diff[2];Mat init_left,init_right;int first_dis,second_dis;float xpos,ypos,zpos;float x_cal_z,x_cal_x1,x_cal_x2;Mat thresleft,thresright;int first_y,y_cal_z;double tan_theta;CalibParam Param;string filehead; };#endif /* defined(__stereo_calibrate_toe__StereoCalib__) */cpp:
#include "StereoCalib.h"void StereoCalib::Process(Mat &left,Mat &right){init_left = left;init_right = right;Triangle_left.clear();Triangle_right.clear();split(left,split_left);split(right, split_right);left_diff[0] = split_left[2] - split_left[1];right_diff[0] = split_right[2] - split_right[1];left_diff[1] = split_left[0] - split_left[1];right_diff[1] = split_right[0] - split_right[1];int total = right_diff[0].rows*right_diff[0].cols;rows = right_diff[0].rows;cols = right_diff[1].cols;thresleft = left_diff[0] + left_diff[1];thresright = right_diff[0] + right_diff[1];threshold(thresleft,thresleft,0,255,THRESH_OTSU);threshold(thresright,thresright,0,255,THRESH_OTSU);thresleft_cp = thresleft.clone();thresright_cp = thresright.clone();findContours(thresleft, contours_left,hierarchy_L,CV_RETR_TREE, CV_CHAIN_APPROX_NONE);findContours(thresright, contours_right,hierarchy_R,CV_RETR_TREE, CV_CHAIN_APPROX_NONE);int tlsize = 0;for(int i=0;i<contours_left.size();i++){approxPolyDP(contours_left[i], approx_left, 10, true);if(approx_left.size() == 4 && hierarchy_L[i][2] == -1 && hierarchy_L[i][3] != -1){contourArea(contours_left[i]);if(contourArea(contours_left[i]) > tlsize){tlsize = contourArea(contours_left[i]);Triangle_left.clear();center_g(contours_left[i], left_center);//circle(left, left_center, 5, Scalar(0,0,0),-1);Triangle_left.push_back(contours_left[i]);}}}for(int i=0;i<Triangle_left.size();i++){\if(tlsize==contourArea(Triangle_left[i])){center_g(Triangle_left[i], left_center);}}circle(left, left_center, 5, Scalar(0,0,0),-1);int trsize = 0;for(int i=0;i<contours_right.size();i++){approxPolyDP(contours_right[i], approx_right, 10, true);if(approx_right.size() == 4 && hierarchy_R[i][2] == -1 && hierarchy_R[i][3] != -1){contourArea(contours_right[i]);if(contourArea(contours_right[i]) > trsize){trsize = contourArea(contours_right[i]);Triangle_right.clear();center_g(contours_right[i], right_center);Triangle_right.push_back(contours_right[i]);}}}for(int i=0;i<Triangle_right.size();i++){\if(trsize==contourArea(Triangle_right[i])){center_g(Triangle_right[i], right_center);}}circle(right, right_center, 5, Scalar(0,0,0),-1);drawContours(left, Triangle_left, -1, Scalar(255,0,0),3);drawContours(right, Triangle_right, -1, Scalar(255,0,0),3);if(Triangle_left.size() == 1 && Triangle_right.size() == 1) VisionDis = abs(left_center.x - right_center.x);distanceCalib();X_calib();Y_calib();Position_show();OtherOption(); }void StereoCalib::KeyParam(int key){this->key = key; }void StereoCalib::Position_show(){if(calib_process > 1 && VisionDis != 0){zpos = Param.distance_const/VisionDis;}if(calib_process > 3 && zpos > 0 && Param.f != 0){xpos = (left_center.x-cols/2)*zpos/Param.f;}if(calib_process > 5 && zpos > 0 && Param.f != 0){ypos = (Param.lightbase- left_center.y)*zpos/Param.f;}ostringstream strx,stry,strz;strx<<"x:"<<xpos<<"mm";stry<<"y:"<<ypos<<"mm";strz<<"z:"<<zpos<<"mm";putText(init_left, strx.str(), Point(cols-180,rows-100),FONT_HERSHEY_COMPLEX , 1, Scalar(255,0,255));putText(init_left, stry.str(), Point(cols-180,rows-70),FONT_HERSHEY_COMPLEX , 1, Scalar(255,0,255));putText(init_left, strz.str(), Point(cols-180,rows-40),FONT_HERSHEY_COMPLEX, 1, Scalar(255,0,255)); }void StereoCalib::distanceCalib(){if(calib_process == 0){putText(init_left, "Press 'd' for 1st position.", Point(100,50), FONT_HERSHEY_COMPLEX_SMALL, 1, Scalar(255,0,255));if(key == 'd'){first_dis = VisionDis;Param.height = rows;Param.width = cols;calib_process = 1;std::cout<<"Move away 10.0cm,then press 'x'."<<std::endl;}}if(calib_process == 1){putText(init_left,"Move away 10.0cm,then press 'x'.", Point(100,50), FONT_HERSHEY_COMPLEX_SMALL, 1, Scalar(255,0,255));if(key == 'x'){second_dis = VisionDis;Param.distance_const = 100.0*((float)(first_dis * second_dis))/((float)(first_dis - second_dis));calib_process = 2;std::cout<<"Stay and press 'd'."<<std::endl;}} }void StereoCalib::X_calib(){if(calib_process == 2){putText(init_left, "Stay and press 'd'.", Point(100,50), FONT_HERSHEY_COMPLEX_SMALL, 1, Scalar(255,0,255));if(key == 'd'){x_cal_z = zpos;x_cal_x1 = left_center.x;calib_process = 3;std::cout<<"Move right 10cm,then press 'x'."<<std::endl;}}if(calib_process == 3){putText(init_left, "Move right 10cm,then press 'x'.", Point(100,50), FONT_HERSHEY_COMPLEX_SMALL, 1, Scalar(255,0,255));if(key == 'x'){x_cal_x2 = left_center.x;Param.f = (x_cal_x2 -x_cal_x1) * x_cal_z / 100.0;calib_process = 4;std::cout<<"Move to first z.Stay and press 'd'."<<std::endl;}} }void StereoCalib::Y_calib(){if(calib_process == 4){putText(init_left, "Move to first z.Stay and press 'd'.", Point(100,50), FONT_HERSHEY_COMPLEX_SMALL, 1, Scalar(255,0,255));if(key == 'd'){first_y = left_center.y;y_cal_z = zpos;calib_process = 5;std::cout<<"Move to second z.Stay and press 'x'."<<std::endl;}}if(calib_process == 5){putText(init_left, "Move to second z.Stay and press 'x'.", Point(100,50), FONT_HERSHEY_COMPLEX_SMALL, 1, Scalar(255,0,255));if(key == 'x'){Param.lightbase = (first_y * y_cal_z - left_center.y * zpos) / (y_cal_z - zpos);calib_process = 6;std::cout<<"finish"<<std::endl;}} }void StereoCalib::OtherOption(){if(calib_process == 6){filehead.append("stereo_calib.xml");FileStorage fs(filehead,FileStorage::WRITE);fs<<"height"<<Param.height<<"width"<<Param.width<<"distance_const"<<Param.distance_const<<"f"<<Param.f<<"lightbase"<<Param.lightbase;fs.release();calib_process = 7;} }void StereoCalib::center_g(const vector<Point> contour,Point ¢er){Moments mu; // Get the center of a contourmu = moments(contour,false);center.x=mu.m10/mu.m00;center.y=mu.m01/mu.m00; }總結
以上是生活随笔為你收集整理的robomaster视觉组代码中的一些函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【项目实战】mybatis +vue.j
- 下一篇: 【练习】不同排序算法执行时间比较