cpp模块备忘录,经常经常用到的函数快
- 读取txt文件数据到数组中,输入txt文件路径,分隔符,输出为数组
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
void ReadDataFromFile(string file_path, vector<Point2f>& data, string pattern)
{
ifstream fin(file_path);
string line_info,input_result;
if(fin)
{
while (getline (fin, line_info)) // line中不包括每行的换行符
{
vector<string> vectorString;
// stringstream input(line_info);
// //依次输出到input_result中,并存入vectorString中
// while(input>>input_result)
// vectorString.push_back(input_result);
// //convert string to float
// data.emplace_back(Point2f(atof(vectorString[0].c_str()),atof(vectorString[1].c_str())));
char * cstr = new char [line_info.length()+1];
std::strcpy (cstr, line_info.c_str());
// cstr now contains a c-string copy of str
char * p = std::strtok (cstr,pattern.c_str());
while (p!=0)
{
vectorString.push_back(p);
p = std::strtok(NULL,pattern.c_str());
}
delete[] cstr;
data.emplace_back(Point2f(atof(vectorString[0].c_str()),atof(vectorString[1].c_str())));
}
}
else // 没有该文件
{
cout<<"no such file"<<endl;;
}
}
int main(void)
{
string img_0_txt = output_path + "/0.png.txt";
vector<Point2f> feature_l_2d;
ReadDataFromFile(img_0_txt, feature_l_2d, " ");
return 0;
}
- 匹配点计算基础矩阵
vector<Point2f> feature_l_2d, feature_m_2d;
for (int i = 0; i < match_l_m.size(); ++i)
{
feature_l_2d.push_back(Point2f(feature_l[match_l_m[i].x].x, feature_l[match_l_m[i].x].y));
feature_m_2d.push_back(Point2f(feature_m[match_l_m[i].y].x, feature_m[match_l_m[i].y].y));
}
//计算F
Mat fundamental_matrix;
vector<uchar> m_RANSACStatus;
fundamental_matrix = findFundamentalMat(feature_l_2d, feature_m_2d, m_RANSACStatus, FM_RANSAC);
std::cout << "opencv 算的基础矩阵F: " << endl << fundamental_matrix << endl;
- 绘制对极线
void DrawEpiLines(const Mat img_1, const Mat img_2, vector<Point2f>points1, vector<Point2f>points2, cv::Mat F,string save_path)
{
std::vector<cv::Vec<float, 3>> epilines;
cv::computeCorrespondEpilines(points1, 1, F, epilines);//计算对应点的外极线epilines是一个三元组(a,b,c),表示点在另一视图中对应的外极线ax+by+c=0;
//将图片转换为RGB图,画图的时候外极线用彩色绘制
cv::Mat img1, img2;
if (img_1.type() == CV_8UC3)
{
img_1.copyTo(img1);
img_2.copyTo(img2);
}
else if (img_1.type() == CV_8UC1)
{
cvtColor(img_1, img1, COLOR_GRAY2BGR);
cvtColor(img_2, img2, COLOR_GRAY2BGR);
}
else
{
std::cout << "unknow img type
" << endl;
exit(0);
}
cv::RNG& rng = theRNG();
for (int i = 0; i < points1.size(); i += 200)
{
Scalar color = Scalar(rng(256), rng(256), rng(256));//随机产生颜色
circle(img1, points1[i], 3, color, 2);//在视图1中把关键点用圆圈画出来
circle(img2, points2[i], 3, color, 2);//在视图2中把关键点用圆圈画出来,然后再绘制在对应点处的外极线
line(img2, Point(0, -epilines[i][2] / epilines[i][1]), Point(img2.cols, -(epilines[i][2] + epilines[i][0] * img2.cols) / epilines[i][1]), color);
}
string img_pointLines = save_path + "/img_pointLines1.png";
string img_point = save_path + "/img_point1.png";
imwrite(img_point, img1);
imwrite(img_pointLines, img2);
}
- 大图按照指定分辨率和布长切片
int crop_row_size = 2400;
int crop_col_size = 2400;
int strip = 1200;
//根据设定尺寸剪裁
int n_col = source_image.cols/strip;
int n_col_res = source_image.cols%strip;
int n_row = source_image.rows/strip;
int n_row_res = source_image.rows%strip;
int end_row = n_row_res==0?n_row:n_row+1;
int end_col = n_col_res==0?n_col:n_col+1;
for(int i = 0;i<end_row;++i)
{
for(int j = 0;j<end_col;++j)
{
int start_x = max(0,min(j * strip,source_image.cols-crop_col_size));
int start_y = max(0,min(i * strip,source_image.rows-crop_row_size));
int rect_width = min(crop_col_size,source_image.cols);
int rect_height= min(crop_row_size,source_image.rows);
Mat crop_image;
source_image(Rect(start_x,start_y,rect_width,rect_height)).copyTo(crop_image);
}
}
- 最大最小聚类
// 计算两个模式样本之间的欧式距离
//仅考虑二维点,模板还不会用...
float get_distance(cv::Point2f data1, cv::Point2f data2)
{
float distance = 0.f;
distance = pow((data1.x-data2.x), 2) + pow((data1.y-data2.y), 2);
return sqrt(distance);
}
// 寻找Z2,并计算阈值T
float step2(vector<cv::Point2f> data,float t, vector<cv::Point2f> & cluster_center)
{
float distance = 0.f;
int index = 0;
for(uint i = 0;i<data.size();++i)
{
//欧氏距离
float temp_distance = get_distance(data[i], cluster_center[0]);
if(temp_distance>distance)
{
distance = temp_distance;
index = i;
}
}
//将Z2加入到聚类中心集中
cluster_center.emplace_back(data[index]);
float T = t * distance; //距离阈值,maxmin聚类的终止条件是: 最大最小距离不大于该阈值
return T;
}
void get_clusters(vector<cv::Point2f> data,vector<cv::Point2f> & cluster_center, float T)
{
float max_min_distance = 0.f;
int index = 0;
for(uint i = 0;i<data.size();++i)
{
vector<float> min_distance_vec;
for(uint j = 0;j<cluster_center.size();++j)
{
float distance = get_distance(data[i],cluster_center[j]);
min_distance_vec.emplace_back(distance);
}
float min_distance = *min_element(min_distance_vec.begin(),min_distance_vec.end());
if(min_distance>max_min_distance)
{
max_min_distance = min_distance;
index = i;
}
}
if(max_min_distance > T)
{
cluster_center.emplace_back(data[index]);
//迭代
get_clusters(data, cluster_center, T);
}
}
//最近邻分类(离哪个聚点中心最近,归为哪类)
vector<vector<cv::Point2f>> classify(vector<cv::Point2f> data, vector<cv::Point2f> & cluster_center, float T)
{
int vec_size = cluster_center.size();
vector<vector<cv::Point2f>> result(vec_size);
for(uint i = 0;i<data.size();++i)
{
float min_distance = T;
int index = 0;
//cout<<"cluster_center size: "<<cluster_center.size()<<endl;
vector<cv::Point2f> temp_vec;
for(uint j = 0;j<cluster_center.size();++j)
{
//cout<<"j is: "<<j<<endl;
float temp_distance = get_distance(data[i], cluster_center[j]);
if(temp_distance < min_distance)
{
min_distance = temp_distance;
index = j;
//cout<<"index is: "<<index<<endl;
}
}
result[index].emplace_back(data[i]);
}
return result;
}
//最大最小聚类
void MaxMinCluster(vector<cv::Point2f> data,vector<vector<cv::Point2f>> & result)
{
assert(data.size()>0);
float t = 0.002;
vector<cv::Point2f> cluster_center; //聚类中心集,选取第一个模式样本作为第一个聚类中心Z1
cluster_center.emplace_back(data[0]);
//第2步:寻找Z2,并计算阈值T
float T = step2(data, t, cluster_center);
// 第3,4,5步,寻找所有的聚类中心
get_clusters(data, cluster_center, T);
// 按最近邻分类
result = classify(data, cluster_center, T);
}