title: solvePNP for planar triangle
body: <p>I have a quite simple task: get Euler angles of a planar triangle.  Pattern looks like <a href="https://w86i.imgup.net/2d6a.png" rel="nofollow noreferrer">this</a></p>
  
  <p>So, the algorithm:</p>
  
  <p>1) get image from webcam -- done</p>
  
  <p>2) convert to gryascale, filter, etc. -- done</p>
  
  <p>3) get mass centers of all connected components, and filter them -- done. Looks like <a href="https://l00i.imgup.net/main7a32.png" rel="nofollow noreferrer">this</a>. Red circles describe mass centers of triangle vertices.</p>
  
  <p>Code is quite simple, but here it is:</p>
  
  <pre><code>QMap&lt;int, QVector&lt;double&gt; &gt; massCenters(const cv::Mat&amp; image)
  {
      cv::Mat output(IMAGE_WIDTH, IMAGE_HEIGHT, CV_32S);
      cv::connectedComponents(image, output, 8);
  
      QMap&lt;int, QVector&lt;double&gt; &gt; result;
  
      for (int y = 0; y &lt; IMAGE_HEIGHT; ++y)
      {
          for (int x = 0; x &lt; IMAGE_WIDTH; ++x)
          {
              int label = output.at&lt;int&gt;(y, x);
  
              if (label)
              {
                  QVector&lt;double&gt; vec = result.value(label, QVector&lt;double&gt;());
  
                  if (vec.isEmpty())
                  {
                      vec.resize(3);
                      vec.fill(0);
                  }
  
                  vec[0] += x;
                  vec[1] += y;
                  vec[2] += 1;
                  result[label] = vec;
              }
           }
      }
  
      return result;
  }
  </code></pre>
  
  <p>4) then I call solvePNP to get rotation &amp; translation vectors</p>
  
  <pre><code> cv::solvePnP(m_origin, m_imagePoints, m_cameraMatrix, m_distMatrix, m_rvec, m_tvec);
  
   //this code is for drawing rvec &amp; tvec on a screen
   std::vector&lt;cv::Point3f&gt; axis;
   vector&lt;cv::Point2f&gt; axis2D;
  
   axis.push_back(Point3f(0.0f, 0.0f, 0.0f));
   axis.push_back(Point3f(30.0f, 0.0f, 0.0f));
   axis.push_back(Point3f(0.0f, 30.0f, 0.0f));
   axis.push_back(Point3f(0.0f, 0.0f, 30.0f));
  
   cv::projectPoints(axis, m_rvec, m_tvec, m_cameraMatrix, m_distMatrix, axis2D);
  
   cv::line(m_orig, axis2D[0], axis2D[1], cv::Scalar(255, 0, 0), 2);
   cv::line(m_orig, axis2D[0], axis2D[2], cv::Scalar(0, 255, 0), 2);
   cv::line(m_orig, axis2D[0], axis2D[3], cv::Scalar(0, 0, 255), 2);
  </code></pre>
  
  <p><strong>m_origin</strong> is declared as <code>std::vector&lt;cv::Point3f&gt; m_origin;</code> and filled with values (measured in mm)</p>
  
  <pre><code>m_origin.push_back(cv::Point3f( 0.0f,   51.0f, 0.0f));
  m_origin.push_back(cv::Point3f(-56.0f, -26.0f, 0.0f));
  m_origin.push_back(cv::Point3f( 56.0f, -26.0f, 0.0f));
  </code></pre>
  
  <p><strong>m_imagePoints</strong> is declared as <code>std::vector&lt;cv::Point2f&gt; m_imagePoints;</code> and contains pixel coordinates of mass centers (red circles on the second screen).</p>
  
  <p>And I get quite strange results: from <a href="https://n82i.imgup.net/bade261.png" rel="nofollow noreferrer">this</a> to <a href="https://w17i.imgup.net/bad21a4c.png" rel="nofollow noreferrer">that</a></p>
  
  <p>What have I tried and it didn't help me:</p>
  
  <p>1) used double and float types in m_cameraMatrix, m_distMatrix, m_rvec, m_tvec</p>
  
  <p>2) rearranged points in m_origin</p>
  
  <p>3) played with solvePnPRansac and it's input parameters</p>
  
  <p>4) played with pnp methods: iterative and epnp</p>
  
  <p>5) useExtrinsicGuess=true -- it helps, but sometimes solution is "stuck" and gives completely wrong values (thousand degrees in rotation vector)</p>
  
  <p>And I have several questions:</p>
  
  <p>1) does order of origin and image points matter? As mentioned <a href="https://github.com/pthom/TestSolvePnp" rel="nofollow noreferrer">here</a>, sometime it does, but it was a year ago.</p>
  
  <p>2) can my task be solved in some other way, than using solvePnP?</p>
  
  <p>Thanks. Would appreciate any help!</p>