bool DictionaryBased::detect(const cv::Mat &in, int & marker_id,int &nRotations) { assert(in.rows == in.cols); cv::Mat grey; if (in.type() == CV_8UC1) grey = in; else cv::cvtColor(in, grey, CV_BGR2GRAY); // threshold image cv::threshold(grey, grey, 125, 255, cv::THRESH_BINARY | cv::THRESH_OTSU); std::vector<uint64_t> ids; //get the ids in the four rotations (if possible) if ( !getInnerCode( grey,_dic.nbits(),ids)) return false; //find the best one for(int i=0;i<4;i++){ if ( _dic.is(ids[i])){//is in the set? nRotations=i;//how many rotations are and its id marker_id=_dic[ids[i]]; return true;//bye bye } } //you get here, no valid id :( //lets try error correction if(_maxCorrectionAllowed>0){//find distance to map elements for(auto ci:_dic.getMapCode()){ for(int i=0;i<4;i++){ if (hamm_distance(ci.first,ids[i])<_maxCorrectionAllowed){ marker_id=ci.second; nRotations=i; return true; } } } } else return false; }
bool DictionaryBased::detect(const cv::Mat& in, int& marker_id, int& nRotations, std::string &additionalInfo) { assert(in.rows == in.cols); cv::Mat grey; if (in.type() == CV_8UC1) grey = in; else cv::cvtColor(in, grey, CV_BGR2GRAY); // threshold image cv::threshold(grey, grey, 125, 255, cv::THRESH_BINARY | cv::THRESH_OTSU); std::map<uint32_t,std::vector<uint64_t> > nbits_ids; //for each for(auto &bitsids:nbits_dict){ int nbits=bitsids.first; std::vector<uint64_t> ids; getInnerCode(grey,nbits,ids); if (ids.size()>0){ if (ids[0]!=0){ nbits_ids[nbits]=ids; } } } //how many are there? if ( nbits_ids.size()==0)return false; //check if any dictionary recognizes it for(auto nbits:nbits_ids){ const auto &ids=nbits.second; //check in every dictionary for(auto &dic:nbits_dict[nbits.first]){ //try a perfecf match for(int rot=0;rot<4;rot++) if ( dic->is( ids[rot])){ // std::cout<<"MATCH:"<<dic->getName()<<" "<<ids[rot]<<std::endl; nRotations = rot; // how many rotations are and its id marker_id = dic->at (ids[rot]); additionalInfo=dic->getName(); return true; } //try with some error/correction if allowed if (_max_correction_rate > 0) { // find distance to map elements int _maxCorrectionAllowed = static_cast<int>( static_cast<float>(dic->tau()) * _max_correction_rate); for (auto ci : dic->getMapCode()) { for (int i = 0; i < 4; i++) { if (hamm_distance(ci.first, ids[i]) < _maxCorrectionAllowed) { marker_id = ci.second; nRotations = i; additionalInfo=dic->getName(); return true; } } } } } } return false; }