32 #include <opencv2/highgui/highgui.hpp> 33 #include <opencv2/imgproc/imgproc.hpp> 36 using namespace aruco;
53 class CmdLineParser{
int argc;
char **argv;
public:
CmdLineParser(
int _argc,
char **_argv):argc(_argc),argv(_argv){}
bool operator[] (
string param ) {
int idx=-1;
for (
int i=0; i<argc && idx==-1; i++ )
if (
string ( argv[i] ) ==param ) idx=i;
return ( idx!=-1 ) ; }
string operator()(
string param,
string defvalue=
"-1"){
int idx=-1;
for (
int i=0; i<argc && idx==-1; i++ )
if (
string ( argv[i] ) ==param ) idx=i;
if ( idx==-1 )
return defvalue;
else return ( argv[ idx+1] ); }};
85 int main(
int argc,
char **argv) {
88 if (argc < 3|| cml[
"-h"]) {
89 cerr <<
"Invalid number of arguments" << endl;
90 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;
98 if (
string(argv[1])==
"live") {
102 if (!
TheVideoCapturer.isOpened())
throw std::runtime_error(
"Could not open video");
110 TheCameraParameters.
resize(TheInputImage.size());
114 if(dict.empty()) dict=
"ARUCO";
116 if (stoi(cml(
"-corner",
"0"))==0)
121 params.
_subpix_wsize= (15./2000.)*float(TheInputImage.cols) ;
132 TheMSPoseTracker.
setParams(TheCameraParameters,TheMarkerMapConfig);
137 cv::namedWindow(
"thres", 1);
138 cv::namedWindow(
"in", 1);
148 cout<<
"Press 's' to start/stop video"<<endl;
154 vector<aruco::Marker> detected_markers=TheMarkerDetector.
detect(TheInputImage);
156 for(
auto idx:TheMarkerMapConfig.
getIndices(detected_markers))
159 if (TheMSPoseTracker.
isValid()){
163 cout<<
"pose rt="<<TheMSPoseTracker.
getRvec()<<
" "<<TheMSPoseTracker.
getTvec()<<endl;
188 }
catch (std::exception &ex)
191 cout <<
"Exception :" << ex.what() << endl;
221 for(
auto idx:TheMarkerMapConfig.
getIndices(detected_markers))
224 if (TheMSPoseTracker.
isValid()){
234 inline float SIGN(
float x) {
return (x >= 0.0
f) ? +1.0f : -1.0f;}
235 inline float NORM(
float a,
float b,
float c,
float d) {
return sqrt(a * a + b * b + c * c + d * d);}
240 assert(M_in.total()==16);
241 cv::Mat M;M_in.convertTo(M,CV_32F);
243 float r11=M.at<
float>(0,0);
244 float r12=M.at<
float>(0,1);
245 float r13=M.at<
float>(0,2);
246 float r21=M.at<
float>(1,0);
247 float r22=M.at<
float>(1,1);
248 float r23=M.at<
float>(1,2);
249 float r31=M.at<
float>(2,0);
250 float r32=M.at<
float>(2,1);
251 float r33=M.at<
float>(2,2);
255 double q0 = ( r11 + r22 + r33 + 1.0f) / 4.0
f;
256 double q1 = ( r11 - r22 - r33 + 1.0f) / 4.0
f;
257 double q2 = (-r11 + r22 - r33 + 1.0f) / 4.0
f;
258 double q3 = (-r11 - r22 + r33 + 1.0f) / 4.0
f;
259 if(q0 < 0.0
f) q0 = 0.0f;
260 if(q1 < 0.0
f) q1 = 0.0f;
261 if(q2 < 0.0
f) q2 = 0.0f;
262 if(q3 < 0.0
f) q3 = 0.0f;
267 if(q0 >= q1 && q0 >= q2 && q0 >= q3) {
269 q1 *=
SIGN(r32 - r23);
270 q2 *=
SIGN(r13 - r31);
271 q3 *=
SIGN(r21 - r12);
272 }
else if(q1 >= q0 && q1 >= q2 && q1 >= q3) {
273 q0 *=
SIGN(r32 - r23);
275 q2 *=
SIGN(r21 + r12);
276 q3 *=
SIGN(r13 + r31);
277 }
else if(q2 >= q0 && q2 >= q1 && q2 >= q3) {
278 q0 *=
SIGN(r13 - r31);
279 q1 *=
SIGN(r21 + r12);
281 q3 *=
SIGN(r32 + r23);
282 }
else if(q3 >= q0 && q3 >= q1 && q3 >= q2) {
283 q0 *=
SIGN(r21 - r12);
284 q1 *=
SIGN(r31 + r13);
285 q2 *=
SIGN(r32 + r23);
288 cerr<<
"Coding error"<<endl;
290 double r =
NORM(q0, q1, q2, q3);
305 std::ofstream file(filename);
306 float qx,qy,qz,qw,tx,ty,tz;
308 if ( !frame.second.empty()){
310 file<<frame.first<<
" "<<tx<<
" "<<ty<<
" "<<tz<<
" "<<qx<<
" "<<qy<<
" "<<qz<<
" "<<qw<<endl;
std::map< int, cv::Mat > frame_pose_map
void setThresholdParams(double param1, double param2)
const cv::Mat getTvec() const
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val)
void resize(cv::Size size)
string TheMarkerMapConfigFile
bool isExpressedInPixels() const
void setCornerRefinementMethod(CornerRefinementMethod method, int val=-1)
bool isExpressedInMeters() const
const cv::Mat getRvec() const
void getThresholdParams(double ¶m1, double ¶m2) const
CameraParameters TheCameraParameters
void setDictionary(std::string dict_type, float error_correction_rate=0)
std::vector< aruco::Marker > detect(const cv::Mat &input)
void readFromFile(string sfile)
static void draw3dAxis(cv::Mat &Image, const CameraParameters &CP, const cv::Mat &Rvec, const cv::Mat &Tvec, float axis_size)
cv::Mat getRTMatrix() const
bool estimatePose(const vector< Marker > &v_m)
void readFromXMLFile(string filePath)
void cvTackBarEvents(int pos, void *)
void setParams(const CameraParameters &cam_params, const MarkerMap &msconf, float markerSize=-1)
MarkerMapPoseTracker TheMSPoseTracker
int main(int argc, char **argv)
MarkerMap convertToMeters(float markerSize)
MarkerMap TheMarkerMapConfig
void savePCDFile(string fpath, const aruco::MarkerMap &ms, const std::map< int, cv::Mat > frame_pose_map)
void getQuaternionAndTranslationfromMatrix44(const cv::Mat &M_in, float &qx, float &qy, float &qz, float &qw, float &tx, float &ty, float &tz)
Main class for marker detection.
VideoCapture TheVideoCapturer
const cv::Mat & getThresholdedImage()
Parameters of the camera.
std::string getDictionary() const
MarkerDetector TheMarkerDetector
void savePosesToFile(string filename, const std::map< int, cv::Mat > &fmp)
std::vector< int > getIndices(vector< aruco::Marker > &markers)
const CwiseUnaryOp< internal::scalar_sqrt_op< Scalar >, const Derived > sqrt() const
float NORM(float a, float b, float c, float d)
CornerRefinementMethod _cornerMethod
This class defines a set of markers whose locations are attached to a common reference system...