linux for windows
vector<thread_data> linemod_match::read_config(string mode, string train_img_dir,string test_img_path,string roi_path,string center_path,string xyz_json,int cam,bool pixel_change_flag){
//圆心及特征点位置txt
string case_num;
case_num = "camera-CCD"+to_string(cam);
fstream _file_txt;
string txt_root=prefix+"/txt/";
_file_txt.open(txt_root, ios::in);
if(!_file_txt)
{
string cmd = "mkdir "+txt_root;
system(cmd.data());
}
_file_txt.close();
string txt_dir=prefix+"/txt/"+case_num+"/";
fstream _file_dir;
_file_dir.open(txt_dir, ios::in);
if(!_file_dir)
{
string cmd = "mkdir "+txt_dir;
system(cmd.data());
}
_file_dir.close();
//
//visualize_dir
string vis_root=prefix+"visualize/";
fstream _file_vis_root;
_file_vis_root.open(vis_root, ios::in);
if(!_file_vis_root)
{
string cmd = "mkdir "+vis_root;
system(cmd.data());
}
_file_vis_root.close();
string vis_dir=prefix+"visualize/"+case_num+"/";
fstream _file_vis;
_file_vis.open(vis_dir, ios::in);
if(!_file_vis)
{
string cmd = "mkdir "+vis_dir;
system(cmd.data());
}
_file_vis.close();
//
//train_dir
string train_dir=prefix+"train/";
fstream _file_tra;
_file_tra.open(train_dir, ios::in);
if(!_file_tra)
{
string cmd = "mkdir "+train_dir;
system(cmd.data());
}
_file_tra.close();
//
string img_path,testimg_path,result_path;
bool write_flag=true;
int num_features = 60;
cv::Mat test_img=cv::imread(test_img_path); //测试图片读取
//改 in here gzr
if(pixel_change_flag) {
srand((int) time(0));
for(int row=0;row<test_img.rows;row++)
for(int col=0;col<test_img.cols;col++)
if(rand()%2)
test_img.at<uchar>(row,col)=min(255, test_img.at<uchar>(row,col)+rand()%5);
else
test_img.at<uchar>(row,col)=max(0, test_img.at<uchar>(row,col)-rand()%5);
}
char *cstr = &roi_path[0];
char* json = getfileAll(cstr);
Json::Reader reader;
Json::Value resp;
map<string,cv::Rect> ROI_test;
if (!reader.parse(json, resp, false))
{
printf("bad json format!\n");
exit(1);
}
Json::Value roi = resp["roi"];
for (int i=0; i<roi.size(); i++) {
string name = roi[i]["name"].asString();
int lx = roi[i]["lx"].asInt();
int ly = roi[i]["ly"].asInt();
int rx = roi[i]["rx"].asInt();
int ry = roi[i]["ry"].asInt();
if(rx>test_img.cols ){
rx=test_img.cols;
}
if(ry>test_img.rows){
ry=test_img.rows;
}
if(lx<0){
lx=0;
}
if(ly<0){
ly=0;
}
cv::Rect cvroi={lx,ly,rx-lx,ry-ly};
ROI_test.insert(pair<string,cv::Rect>(name,cvroi));
}
//读取总的中心点json
ifstream jsonFile(center_path);
nlohmann::json centerset;
jsonFile >> centerset;
///数据读取完毕
vector<thread_data> td_train;
vector<thread_data> td_test;
if(mode=="train"){
map<string,cv::Rect>::iterator roi_test_it;
int k=0;
for(roi_test_it=ROI_test.begin();roi_test_it!=ROI_test.end();roi_test_it++){
string name=roi_test_it->first; //"PM31"
cv::Rect roi_circle=roi_test_it->second; //cv::Rect roi
nlohmann::json X = centerset[name]["X"];
nlohmann::json Y = centerset[name]["Y"];
nlohmann::json Z = centerset[name]["Z"];
nlohmann::json d = centerset[name]["diameter"]; //直径读取
if(X== nullptr ||Y==nullptr ||Z== nullptr || d == nullptr){
continue;
}
//只训练补充那些漏掉的
// string templ_path=prefix+"train/"+case_num+"_"+name+"_templ"+"-"+to_string(num_features)+"-4-8.yaml";
// fstream _file_tmp_tr;
// _file_tmp_tr.open(templ_path, ios::in);
// if(_file_tmp_tr)
// {
// continue;
// }
// _file_tmp_tr.close();
//
string tmp_path=prefix+"/"+case_num+"/"+name+"/";
fstream _file_tmp;
_file_tmp.open(tmp_path, ios::in);
if(!_file_tmp)
{
continue;
}
_file_tmp.close();
cout<<"name:"<<name<<endl;
cout<<"diameter:"<<d<<endl;
float gt_radius=float(d)/2;
// float gt_radius=1;
thread_data tmp_tr;
//训练数据
tmp_tr.mode="train";
tmp_tr.case_num=case_num; //相机编号
tmp_tr.objid=name; //孔编号
tmp_tr.img_path=train_img_dir+name+"/";
tmp_tr.test_img=test_img;
tmp_tr.num_feature=num_features;
tmp_tr.write_flag= write_flag;
tmp_tr.ROI_img=roi_circle;
tmp_tr.gt_radius=gt_radius;
td_train.push_back(tmp_tr);
//print check
cout<<"mode: "<<tmp_tr.mode<<endl;
cout<<"case_num: "<<tmp_tr.case_num<<endl;
cout<<"id: "<<tmp_tr.objid<<endl;
cout<<"objid: "<<tmp_tr.objid<<endl;
cout<<"img_path: "<<tmp_tr.img_path<<endl;
cout<<"num_feature: "<<tmp_tr.num_feature<<endl;
cout<<endl;
k++;
}
return td_train;
}
else{
map<string,cv::Rect>::iterator roi_test_it;
int k=0;
for(roi_test_it=ROI_test.begin();roi_test_it!=ROI_test.end();roi_test_it++){
string name=roi_test_it->first; //"PM31"
cv::Rect roi_circle=roi_test_it->second; //cv::Rect roi
nlohmann::json X = centerset[name]["X"];
nlohmann::json Y = centerset[name]["Y"];
nlohmann::json Z = centerset[name]["Z"];
nlohmann::json d = centerset[name]["diameter"]; //直径读取
//modify
// if(X== nullptr ||Y==nullptr ||Z== nullptr){
// continue;
// }
if( d == nullptr){
d=1;
}
//test的时候训练文件不存在才会跳过
string templ_path=prefix+"train/"+case_num+"_"+name+"_templ"+"-"+to_string(num_features)+"-4-8.yaml";
fstream _file_tmp;
_file_tmp.open(templ_path, ios::in);
if(!_file_tmp)
{
continue;
}
_file_tmp.close();
float gt_radius=float(d)/2;
//测试数据
thread_data tmp_te;
tmp_te.mode="test";
tmp_te.case_num=case_num;
tmp_te.objid=name;
tmp_te.img_path=train_img_dir+name+"/";
tmp_te.test_img=test_img;
tmp_te.num_feature=num_features;
tmp_te.write_flag = write_flag;
tmp_te.ROI_img=roi_circle;
tmp_te.gt_radius=gt_radius;
td_test.push_back(tmp_te);
//print check
cout<<"mode: "<<tmp_te.mode<<endl;
cout<<"case_num: "<<tmp_te.case_num<<endl;
cout<<"objid: "<<tmp_te.objid<<endl;
cout<<"img_path: "<<tmp_te.img_path<<endl;
cout<<"num_feature: "<<tmp_te.num_feature<<endl;
cout<<"write_flag: "<<tmp_te.write_flag<<endl;
cout<<"ROI_image_test: "<<tmp_te.ROI_img<<endl;
cout<<"gt_radius: "<<tmp_te.gt_radius<<endl;
k++;
}
return td_test;
}
}
map<string,rad_err> linemod_match::match_final(string path){
srand((unsigned) time(NULL));//diff color
MIPP_test();
time_t begin,end;
double duration;
begin=clock();
map<string,rad_err> map_match[5];
cout << "开始计算时间 .... " << endl;
cv::FileStorage fsall(path, cv::FileStorage::READ);
//check the yaml file in the path exsit.
if (!fsall.isOpened()) {
fprintf(stderr, "%s:%d:loadParams falied. 'config.yaml' does not exist\n", __FILE__, __LINE__);
exit(1);
}
int NUM_CAMS = (int)fsall["NUM_CAMS"];
string train_root;
string roi_root;
string test_img_root;
string center_json;
string all_mode;
string xyz_json;
fsall["train_root"]>>train_root;
fsall["roi_root"]>>roi_root;
fsall["test_img_root"]>>test_img_root;
fsall["center_json"]>>center_json;
fsall["all_mode"]>>all_mode;
fsall["xyz_json"]>>xyz_json;
cout<<"cam:"<<NUM_CAMS<<endl;
cout<<"center_json"<<center_json<<endl;
fsall.release();
cout<<"***************"<<endl;
//读取最终的三坐标中心点json
ifstream xyz_json_file(xyz_json);
nlohmann::json xyz_d_set;
xyz_json_file >> xyz_d_set;
//配置文件读取完毕
// omp_set_num_threads(4);
//#pragma omp parallel for
for (int i=0;i<5;i++){ //相机台数 NUM_CAMS 24
// cout<<"max_threads: "<<omp_get_max_threads()<<endl;
// 删除txt文件
string txt_dir=prefix+"txt/"+"camera-CCD"+to_string(i+1)+"/";
fstream _file_rmtxt;
//c_str():生成一个const char*指针,指向以空字符终止的数组。
const char *txt_path=(txt_dir).c_str();
_file_rmtxt.open(txt_dir, ios::in); //if result dir not exist, mkdir
if(_file_rmtxt) //如果存在 /txt/" 就删除,使得ofstream可以重新创建
{
auto namelist=file_search2(txt_dir,"*.txt");
if (namelist.size()!=0){
//删除txt文件
for(int k=0;k<namelist.size();k++){
string cur_txt=txt_dir+namelist[k];
fstream _file_rmtxt;
const char *txt_path=(cur_txt).c_str();
_file_rmtxt.open(txt_path, ios::in); //if result dir exist
if(_file_rmtxt) //如果存在 result_path+"result.txt" 就删除,使得ofstream可以重新创建
{
remove(txt_path);
}
_file_rmtxt.close();
}
}
}
_file_rmtxt.close();
// if(i+1==19 ||i+1==20){ //19 20模糊的两组用来测平面度的直接跳过
// continue;
// }
string train_img_dir = train_root+"camera-CCD"+to_string(i+1)+"/";
string current_roi=roi_root+"camera-CCD"+to_string(i+1)+".json"; //每个相机的roi json文件,于洋给出
string test_img_path=test_img_root+"CCD"+to_string(i+1)+".bmp";
//获取圆数目
char *cstr = ¤t_roi[0];
char* json = getfileAll(cstr);
Json::Reader reader;
Json::Value resp;
if (!reader.parse(json, resp, false))
{
printf("bad json format!\n");
exit(1);
}
Json::Value roi = resp["roi"];
int circle_per_cam=roi.size();
cout<<"circle_per_cam:"<<circle_per_cam<<endl;
cout<<"************ finish reading config ************"<<endl;
cout<<endl;
if(all_mode=="train"){
cout<<"I has entered train stage:\n";
getchar();
auto td_train=read_config("train",train_img_dir,test_img_path,current_roi,center_json,xyz_json,i+1, false); //center_json 名义值 xyz_json测量值
for (int j=0;j<td_train.size();j++){
//6边型
string c_name=td_train[j].objid;//孔编号
auto rad=angle_test(td_train[j]);
}
//gzr, 训练部分应该不需要
// for(int cur_img=0;cur_img<4;cur_img++){
//
// for (int j=0;j<td_train.size();j++){
// //6边型
// string c_name=td_train[j].objid;//孔编号
// auto rad=angle_test(td_train[j],false);
// }
// }
}
else{
for(int cur_img=0;cur_img<5;cur_img++){
//if cur_img==0 cur_img!=0为false,no change
auto td_test=read_config("test",train_img_dir,test_img_path,current_roi,center_json,xyz_json,i+1, cur_img!=0); //center_json 名义值 xyz_json测量值
for (int j=0;j<td_test.size();j++){
string c_name=td_test[j].objid;
auto rad=angle_test(td_test[j]);//
td_test[j].test_img.release();
// nlohmann::json xyz_name= xyz_d_set[c_name];
// if(xyz_name==nullptr) //不存在
// continue;
nlohmann::json D= xyz_d_set[c_name]["D"];
rad.flag= false; //flag为false代表有测量半径
// if(D== nullptr)
// continue;
if(D == nullptr){
D=rad.radius*2;
rad.flag= true; //无测量半径,但是要测位置度
}
double r_real=double(D)/2;
rad.error=abs(rad.radius-r_real);
rad.cam=i+1;
if(rad.flag==false){ //只返回有半径的,对于无半径的,图像上的圆心已经写入txt了
if(map_match[cur_img].count(c_name)==0 && rad.radius!=100) //不存在 直接插入
{
map_match[cur_img].insert(pair<string , rad_err >(c_name,rad));
}
if(map_match[cur_img].count(c_name)>0) //存在
{
//#pragma omp critical
{
if (map_match[cur_img][c_name].error > rad.error) //如果map_error里的圆孔误差比当前大,更新误差
{
map_match[cur_img][c_name].radius = rad.radius;
map_match[cur_img][c_name].error = rad.error;
map_match[cur_img][c_name].cam =rad.cam;
}
}
}
}
}
}
}
}
cout<<"****** end over ******"<<endl;
end=clock();
duration=double(end-begin)/CLOCKS_PER_SEC;
cout<<"runtime: "<<duration<<" s"<<endl;
out_gzr.close();
//为了节省空间,直接吧map_match[0]求解平均之后return
map<string,rad_err>::iterator iter;
//分别表示空间名称,平均之后的半径和出现次数
string c_name;double ave_radius=0;int cnt=0;
for(iter=map_match[0].begin();iter!=map_match[0].end();iter++){
c_name=(*iter).first;
ave_radius=(*iter).second.radius;
cnt=1;
for(int i=1;i<5;i++){
if(map_match[i].count(c_name)!=0) {
ave_radius += map_match[i][c_name].radius;
cnt++;
}
}
map_match[0][c_name].radius=ave_radius/cnt;
cout<<c_name<<" "<<map_match[0][c_name].radius<<" "<<map_match[0][c_name].error<<endl;
}
return map_match[0];
}
不疯魔不成活