终于等到你

众里寻他千百度,蓦然回首,那人却在灯火阑珊处。

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 = &current_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];
}
posted @ 2020-08-10 19:32  gzr2018  阅读(148)  评论(0编辑  收藏  举报