Origin not in center of Aruco marker

Hello,

Yes, small mistake for me with the /2, I removed it but it does not change anything. I also tried to set the distortion to 0 but still the same result.

The camera simulated on Gazebo is 640 by 360 resolution.

I did the test with a webcam and the result in real is the same. I removed all the non-opencv code and here is the result:

The resolution of the camera is 1280x720.

And here is my code used for the webcam test :

// opencv modules
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/aruco.hpp>
#include <opencv2/core/types.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/gapi.hpp>

#include <iostream>

using namespace std;
using namespace cv;

int main(int argc, char* argv[])
{
  //settings camera C270
  float mtx[3][3] = {
       {794.71614391, 0.00000000e+00, 347.55631962 } ,
       {0.00000000e+00, 794.71614391, 293.50160806} ,
       {0.00000000e+00, 0.00000000e+00, 1.00000000e+00}
       };
  float dist[14][1] = {
       {-2.45415937e-01} ,
       {-6.48440697e+00} ,
       {3.54169640e-02} ,
       {9.11031500e-03} ,
       {-1.09181519e+02} ,
       {-1.23188350e-01} ,
       {-7.76776901e+00} ,
       {-1.05816513e+02} ,
       {0.00000000e+00} ,
       {0.00000000e+00} ,
       {0.00000000e+00} ,
       {0.00000000e+00} ,
       {0.00000000e+00} ,
       {0.00000000e+00}
       };

       cv::Mat camMatrix = cv::Mat(3, 3, CV_32F, mtx);
       cv::Mat distCoeffs = cv::Mat(14, 1, CV_32F, dist);

  cv::VideoCapture inputVideo;
  inputVideo.open(0);
  cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250);
  while (inputVideo.grab())
  {
      cv::Mat image, imageCopy;
      inputVideo.retrieve(image);
      image.copyTo(imageCopy);
      std::vector<int> ids;
      std::vector<std::vector<cv::Point2f> > corners;
      std::vector<cv::Vec3d> rvecs, tvecs;
      cv::aruco::detectMarkers(image, dictionary, corners, ids);

      if (ids.size() > 0)
      {
          cv::aruco::drawDetectedMarkers(imageCopy, corners, ids);
          cv::aruco::estimatePoseSingleMarkers(corners,0.12 , camMatrix, distCoeffs, rvecs, tvecs);

          // project axis points
          vector< Point3f > axisPoints;
          axisPoints.push_back(Point3f(0, 0, 0));
          axisPoints.push_back(Point3f(0.12, 0, 0));
          axisPoints.push_back(Point3f(0, 0.12, 0));
          axisPoints.push_back(Point3f(0, 0, 0.12));
          vector< Point2f > imagePoints;
          projectPoints(axisPoints, rvecs, tvecs, camMatrix, distCoeffs, imagePoints);
          line(imageCopy, imagePoints[0], imagePoints[1], Scalar(0, 0, 255), 3);
          line(imageCopy, imagePoints[0], imagePoints[2], Scalar(0, 255, 0), 3);
          line(imageCopy, imagePoints[0], imagePoints[3], Scalar(255, 0, 0), 3);
        }

    cv::imshow("out", imageCopy);
    char key = (char) cv::waitKey(10);
    if (key == 27)
        break;
  }
 return 0;
}

Maybe I should try with a Python only code.

Thanks for opening an issue about this. The result is quite annoying on my side.

Thanks for the help. Really appreciate it.