void cvTackBarEvents(int pos,void*) { if (iThresParam1<3) iThresParam1=3; if (iThresParam1%2!=1) iThresParam1++; if (ThresParam2<1) ThresParam2=1; ThresParam1=iThresParam1; ThresParam2=iThresParam2; MDetector.setThresholdParams(ThresParam1,ThresParam2); //recompute MDetector.detect(TheInputImage,TheMarkers,TheCameraParameters); TheInputImage.copyTo(TheInputImageCopy); for (unsigned int i=0;i<TheMarkers.size();i++) TheMarkers[i].draw(TheInputImageCopy,Scalar(0,0,255),1); //print other rectangles that contains no valid markers for (unsigned int i=0;i<MDetector.getCandidates().size();i++) { aruco::Marker m( MDetector.getCandidates()[i],999); m.draw(TheInputImageCopy,cv::Scalar(255,0,0)); } //draw a 3d cube in each marker if there is 3d info if (TheCameraParameters.isValid()) for (unsigned int i=0;i<TheMarkers.size();i++) CvDrawingUtils::draw3dCube(TheInputImageCopy,TheMarkers[i],TheCameraParameters); cv::imshow("in",TheInputImageCopy); cv::imshow("thres",MDetector.getThresholdedImage()); }
void cvTackBarEvents(int pos, void*) { (void)(pos); if (iThresParam1 < 3) iThresParam1 = 3; if (iThresParam1 % 2 != 1) iThresParam1++; if (iThresParam1 < 1) iThresParam1 = 1; MDetector.setThresholdParams(iThresParam1, iThresParam2); if (iEnclosedMarkers){ auto params=MDetector.getParams(); params._doErosion=true; params._cornerMethod=aruco::MarkerDetector::SUBPIX; MDetector.setParams(params); } else{ auto params=MDetector.getParams(); params._doErosion=false; params._cornerMethod=aruco::MarkerDetector::LINES; MDetector.setParams(params); } MDetector.setDictionary(dictionaryString,float(iCorrectionRate)/10. ); // sets the dictionary to be employed (ARUCO,APRILTAGS,ARTOOLKIT,etc) // recompute MDetector.detect(TheInputImage, TheMarkers, TheCameraParameters); TheInputImage.copyTo(TheInputImageCopy); if (iShowAllCandidates){ auto candidates=MDetector.getCandidates(); for(auto cand:candidates) Marker(cand,-1).draw(TheInputImageCopy, Scalar(255, 0, 255)); } for (unsigned int i = 0; i < TheMarkers.size(); i++) TheMarkers[i].draw(TheInputImageCopy, Scalar(0, 0, 255)); // draw a 3d cube in each marker if there is 3d info if (TheCameraParameters.isValid()) for (unsigned int i = 0; i < TheMarkers.size(); i++) CvDrawingUtils::draw3dCube(TheInputImageCopy, TheMarkers[i], TheCameraParameters); cv::imshow("in", resize(TheInputImageCopy, 1280)); cv::imshow("thres", resize(MDetector.getThresholdedImage(), 1280)); }
int main(int argc, char** argv) { try { CmdLineParser cml(argc, argv); if (argc < 2 || cml["-h"]) { cerr << "Invalid number of arguments" << endl; cerr << "Usage: (in.avi|live[:camera_index(e.g 0 or 1)]) [-c camera_params.yml] [-s marker_size_in_meters] [-d " "dictionary:ARUCO by default] [-h]" << endl; cerr << "\tDictionaries: "; for (auto dict : aruco::Dictionary::getDicTypes()) cerr << dict << " "; cerr << endl; cerr << "\t Instead of these, you can directly indicate the path to a file with your own generated " "dictionary" << endl; return false; } /////////// PARSE ARGUMENTS string TheInputVideo = argv[1]; // read camera parameters if passed if (cml["-c"]) TheCameraParameters.readFromXMLFile(cml("-c")); float TheMarkerSize = std::stof(cml("-s", "-1")); // aruco::Dictionary::DICT_TYPES TheDictionary= Dictionary::getTypeFromString( cml("-d","ARUCO") ); /////////// OPEN VIDEO // read from camera or from file if (TheInputVideo.find("live") != string::npos) { int vIdx = 0; // check if the :idx is here char cad[100]; if (TheInputVideo.find(":") != string::npos) { std::replace(TheInputVideo.begin(), TheInputVideo.end(), ':', ' '); sscanf(TheInputVideo.c_str(), "%s %d", cad, &vIdx); } cout << "Opening camera index " << vIdx << endl; TheVideoCapturer.open(vIdx); waitTime = 10; } else TheVideoCapturer.open(TheInputVideo); // check video is open if (!TheVideoCapturer.isOpened()) throw std::runtime_error("Could not open video"); ///// CONFIGURE DATA // read first image to get the dimensions TheVideoCapturer >> TheInputImage; if (TheCameraParameters.isValid()) TheCameraParameters.resize(TheInputImage.size()); dictionaryString=cml("-d", "ARUCO"); MDetector.setDictionary(dictionaryString,float(iCorrectionRate)/10. ); // sets the dictionary to be employed (ARUCO,APRILTAGS,ARTOOLKIT,etc) MDetector.setThresholdParams(7, 7); MDetector.setThresholdParamRange(2, 0); // gui requirements : the trackbars to change this parameters iThresParam1 = static_cast<int>(MDetector.getParams()._thresParam1); iThresParam2 = static_cast<int>(MDetector.getParams()._thresParam2); cv::namedWindow("in"); cv::createTrackbar("ThresParam1", "in", &iThresParam1, 25, cvTackBarEvents); cv::createTrackbar("ThresParam2", "in", &iThresParam2, 13, cvTackBarEvents); cv::createTrackbar("correction_rate", "in", &iCorrectionRate, 10, cvTackBarEvents); cv::createTrackbar("EnclosedMarkers", "in", &iEnclosedMarkers, 1, cvTackBarEvents); cv::createTrackbar("ShowAllCandidates", "in", &iShowAllCandidates, 1, cvTackBarEvents); // go! char key = 0; int index = 0,indexSave=0; // capture until press ESC or until the end of the video do { TheVideoCapturer.retrieve(TheInputImage); // copy image double tick = (double)getTickCount(); // for checking the speed // Detection of markers in the image passed TheMarkers = MDetector.detect(TheInputImage, TheCameraParameters, TheMarkerSize); // chekc the speed by calculating the mean speed of all iterations AvrgTime.first += ((double)getTickCount() - tick) / getTickFrequency(); AvrgTime.second++; cout << "\rTime detection=" << 1000 * AvrgTime.first / AvrgTime.second << " milliseconds nmarkers=" << TheMarkers.size() << std::endl; // print marker info and draw the markers in image TheInputImage.copyTo(TheInputImageCopy); if (iShowAllCandidates){ auto candidates=MDetector.getCandidates(); for(auto cand:candidates) Marker(cand,-1).draw(TheInputImageCopy, Scalar(255, 0, 255)); } for (unsigned int i = 0; i < TheMarkers.size(); i++) { cout << TheMarkers[i] << endl; TheMarkers[i].draw(TheInputImageCopy, Scalar(0, 0, 255)); } // draw a 3d cube in each marker if there is 3d info if (TheCameraParameters.isValid() && TheMarkerSize > 0) for (unsigned int i = 0; i < TheMarkers.size(); i++) { CvDrawingUtils::draw3dCube(TheInputImageCopy, TheMarkers[i], TheCameraParameters); CvDrawingUtils::draw3dAxis(TheInputImageCopy, TheMarkers[i], TheCameraParameters); } // DONE! Easy, right? // show input with augmented information and the thresholded image cv::imshow("in", resize(TheInputImageCopy, 1280)); cv::imshow("thres", resize(MDetector.getThresholdedImage(), 1280)); key = cv::waitKey(waitTime); // wait for key to be pressed if (key == 's') waitTime = waitTime == 0 ? 10 : 0; if (key == 'w'){//writes current input image string number=std::to_string(indexSave++); while(number.size()!=3)number+="0"; string imname="arucoimage"+number+".png"; cv::imwrite(imname,TheInputImage); cout<<"saved "<<imname<<endl; } index++; // number of images captured } while (key != 27 && (TheVideoCapturer.grab())); } catch (std::exception& ex) { cout << "Exception :" << ex.what() << endl; } }