void AddControlPointsWithCheck(CPVector &cpv, CPVector &new_cp, Panorama *pano=NULL) { for(unsigned int i=0;i<new_cp.size();i++) { HuginBase::ControlPoint cp=new_cp[i]; bool duplicate=false; for(unsigned int j=0;j<cpv.size();j++) { if(cp==cpv[j]) { duplicate=true; break; } }; if(!duplicate) { cpv.push_back(cp); if(pano!=NULL) pano->addCtrlPoint(cp); }; }; };
CPVector AutoPanoSiftMultiRowStack::automatch(CPDetectorSetting &setting, Panorama & pano, const UIntSet & imgs, int nFeatures, int & ret_value, wxWindow *parent) { CPVector cps; if (imgs.size() == 0) { return cps; }; std::vector<stack_img> stack_images; HuginBase::StandardImageVariableGroups* variable_groups = new HuginBase::StandardImageVariableGroups(pano); for(UIntSet::const_iterator it = imgs.begin(); it != imgs.end(); it++) { unsigned int stack_nr=variable_groups->getStacks().getPartNumber(*it); //check, if this stack is already in list bool found=false; unsigned int index=0; for(index=0;index<stack_images.size();index++) { found=(stack_images[index].layer_nr==stack_nr); if(found) break; }; if(!found) { //new stack stack_images.resize(stack_images.size()+1); index=stack_images.size()-1; //add new stack stack_images[index].layer_nr=stack_nr; }; //add new image unsigned int new_image_index=stack_images[index].images.size(); stack_images[index].images.resize(new_image_index+1); stack_images[index].images[new_image_index].img_nr=*it; stack_images[index].images[new_image_index].ev=pano.getImage(*it).getExposure(); }; delete variable_groups; //get image with median exposure for search with cp generator UIntSet images_layer; for(unsigned int i=0;i<stack_images.size();i++) { std::sort(stack_images[i].images.begin(),stack_images[i].images.end(),sort_img_ev); unsigned int index=0; if(stack_images[i].images[0].ev!=stack_images[i].images[stack_images[i].images.size()-1].ev) { index=stack_images[i].images.size() / 2; }; images_layer.insert(stack_images[i].images[index].img_nr); }; ret_value=0; //work on all stacks if(!setting.GetProgStack().IsEmpty()) { CPDetectorSetting stack_setting; stack_setting.SetType(CPDetector_AutoPanoSift); stack_setting.SetProg(setting.GetProgStack()); stack_setting.SetArgs(setting.GetArgsStack()); for(unsigned int i=0;i<stack_images.size();i++) { UIntSet images_stack; images_stack.clear(); for(unsigned int j=0;j<stack_images[i].images.size();j++) images_stack.insert(stack_images[i].images[j].img_nr); if(images_stack.size()>1) { AutoPanoSift matcher; CPVector new_cps=matcher.automatch(stack_setting, pano, images_stack, nFeatures, ret_value, parent); if(new_cps.size()>0) AddControlPointsWithCheck(cps,new_cps); if(ret_value!=0) { std::vector<wxString> emptyKeyfiles; Cleanup(setting, pano, imgs, emptyKeyfiles, parent); return cps; }; }; }; } //generate cp for median exposure with multi-row algorithm if(images_layer.size()>1) { UIntSet allImgs; fill_set(allImgs, 0, pano.getNrOfImages()-1); Panorama newPano=pano.getSubset(allImgs); if(cps.size()>0) for (CPVector::const_iterator it=cps.begin();it!=cps.end();++it) newPano.addCtrlPoint(*it); AutoPanoSiftMultiRow matcher; CPVector new_cps=matcher.automatch(setting, newPano, images_layer, nFeatures, ret_value, parent); if(new_cps.size()>0) AddControlPointsWithCheck(cps,new_cps); }; return cps; };