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; } }
int main(int argc, char** argv) { try { CmdLineParser cml(argc, argv); if (argc < 3 || cml["-h"]) { cerr << "Invalid number of arguments" << endl; cerr << "Usage: (in.avi|live) marksetconfig.yml [optional_arguments] \n\t[-c camera_intrinsics.yml] " "\n\t[-s marker_size] \n\t[-pcd out_pcd_file_with_camera_poses] \n\t[-poses out_file_with_poses] " "\n\t[-corner <corner_refinement_method> (0: LINES(default),1 SUBPIX) ][-h]" << endl; return false; } TheMarkerMapConfig.readFromFile(argv[2]); TheMarkerMapConfigFile = argv[2]; TheMarkerSize = stof(cml("-s", "1")); // read from camera or from file if (string(argv[1]) == "live") { TheVideoCapturer.open(0); } else TheVideoCapturer.open(argv[1]); // check video is open if (!TheVideoCapturer.isOpened()) throw std::runtime_error("Could not open video"); // read first image to get the dimensions TheVideoCapturer >> TheInputImage; // read camera parameters if passed if (cml["-c"]) { TheCameraParameters.readFromXMLFile(cml("-c")); TheCameraParameters.resize(TheInputImage.size()); } // prepare the detector string dict = TheMarkerMapConfig .getDictionary(); // see if the dictrionary is already indicated in the configuration file. It should! if (dict.empty()) dict = "ARUCO"; TheMarkerDetector.setDictionary( dict); /// DO NOT FORGET THAT!!! Otherwise, the ARUCO dictionary will be used by default! if (stoi(cml("-corner", "0")) == 0) TheMarkerDetector.setCornerRefinementMethod(MarkerDetector::LINES); else { MarkerDetector::Params params = TheMarkerDetector.getParams(); params._cornerMethod = MarkerDetector::SUBPIX; // search corner subpix in a 5x5 widow area params._subpix_wsize = static_cast<int>((15.f / 2000.f) * float(TheInputImage.cols)); TheMarkerDetector.setParams(params); } // prepare the pose tracker if possible // if the camera parameers are avaiable, and the markerset can be expressed in meters, then go if (TheMarkerMapConfig.isExpressedInPixels() && TheMarkerSize > 0) TheMarkerMapConfig = TheMarkerMapConfig.convertToMeters(TheMarkerSize); cout << "TheCameraParameters.isValid()=" << TheCameraParameters.isValid() << " " << TheMarkerMapConfig.isExpressedInMeters() << endl; if (TheCameraParameters.isValid() && TheMarkerMapConfig.isExpressedInMeters()) TheMSPoseTracker.setParams(TheCameraParameters, TheMarkerMapConfig); // Create gui cv::namedWindow("thres", 1); cv::namedWindow("in", 1); TheMarkerDetector.getThresholdParams(ThresParam1, ThresParam2); iThresParam1 = static_cast<int>(ThresParam1); iThresParam2 = static_cast<int>(ThresParam2); cv::createTrackbar("ThresParam1", "in", &iThresParam1, 13, cvTackBarEvents); cv::createTrackbar("ThresParam2", "in", &iThresParam2, 13, cvTackBarEvents); char key = 0; int index = 0; // capture until press ESC or until the end of the video cout << "Press 's' to start/stop video" << endl; do { TheVideoCapturer.retrieve(TheInputImage); TheInputImage.copyTo(TheInputImageCopy); index++; // number of images captured // Detection of the board vector<aruco::Marker> detected_markers = TheMarkerDetector.detect(TheInputImage); // print the markers detected that belongs to the markerset for (auto idx : TheMarkerMapConfig.getIndices(detected_markers)) detected_markers[idx].draw(TheInputImageCopy, Scalar(0, 0, 255), 2); // detect 3d info if possible if (TheMSPoseTracker.isValid()) { if (TheMSPoseTracker.estimatePose(detected_markers)) { aruco::CvDrawingUtils::draw3dAxis(TheInputImageCopy, TheCameraParameters, TheMSPoseTracker.getRvec(), TheMSPoseTracker.getTvec(), TheMarkerMapConfig[0].getMarkerSize() * 2); frame_pose_map.insert(make_pair(index, TheMSPoseTracker.getRTMatrix())); cout << "pose rt=" << TheMSPoseTracker.getRvec() << " " << TheMSPoseTracker.getTvec() << endl; } } // show input with augmented information and the thresholded image cv::imshow("in", TheInputImageCopy); cv::imshow("thres", TheMarkerDetector.getThresholdedImage()); key = cv::waitKey(waitTime); // wait for key to be pressed processKey(key); } while (key != 27 && TheVideoCapturer.grab()); // save a beatiful pcd file (pcl library) showing the results (you can use pcl_viewer to see it) if (cml["-pcd"]) { savePCDFile(cml("-pcd"), TheMarkerMapConfig, frame_pose_map); } // save the poses to a file in tum rgbd data format if (cml["-poses"]) { savePosesToFile(cml("-poses"), frame_pose_map); } } catch (std::exception& ex) { cout << "Exception :" << ex.what() << endl; } }