2017-03-24 39 views
1

我有一個相當簡單的任務:獲得平面三角形的歐拉角。圖案看起來像thissolvePNP用於平面三角形

所以,算法:

1)從網絡攝像頭獲取的圖像 - 做

2)轉換爲gryascale,過濾器等 - 進行

3)獲得所有連接組件的質量中心,並過濾它們 - 完成。看起來像this。紅色圓圈描述三角形頂點的質心。

代碼非常簡單,但在這裏它是:

QMap<int, QVector<double> > massCenters(const cv::Mat& image) 
{ 
    cv::Mat output(IMAGE_WIDTH, IMAGE_HEIGHT, CV_32S); 
    cv::connectedComponents(image, output, 8); 

    QMap<int, QVector<double> > result; 

    for (int y = 0; y < IMAGE_HEIGHT; ++y) 
    { 
     for (int x = 0; x < IMAGE_WIDTH; ++x) 
     { 
      int label = output.at<int>(y, x); 

      if (label) 
      { 
       QVector<double> vec = result.value(label, QVector<double>()); 

       if (vec.isEmpty()) 
       { 
        vec.resize(3); 
        vec.fill(0); 
       } 

       vec[0] += x; 
       vec[1] += y; 
       vec[2] += 1; 
       result[label] = vec; 
      } 
     } 
    } 

    return result; 
} 

4)然後我打電話solvePNP得到旋轉&翻譯載體

cv::solvePnP(m_origin, m_imagePoints, m_cameraMatrix, m_distMatrix, m_rvec, m_tvec); 

//this code is for drawing rvec & tvec on a screen 
std::vector<cv::Point3f> axis; 
vector<cv::Point2f> 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); 

m_origin被聲明爲std::vector<cv::Point3f> m_origin;和充滿值(以mm爲單位)

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)); 

m_imagePoints被聲明爲std::vector<cv::Point2f> m_imagePoints;幷包含質心的像素座標(第二個屏幕上的紅色圓圈)。

我變得非常奇怪的結果:從thisthat

有什麼我想並沒有幫助我:

1)使用雙和m_cameraMatrix,m_distMatrix,m_rvec,m_tvec float類型

2)在m_origin

3重新排列的點)與solvePnPRansac播放並且它的輸入參數

4)使用了與PNP方法:迭代和EPNP

5)useExtrinsicGuess =真 - 它可以幫助,但有時的解決方案是「套牢」,並給出了完全錯誤的值(旋轉矢量萬度)

而且我有幾個問題:

1)請問原點和圖像點順序有關係嗎?正如here提到的那樣,有時它確實,但是它是一年前。

2)我的任務可以通過其他方式解決,比使用solvePnP?

謝謝。將不勝感激任何幫助!

回答

2

solvePnPRansac不適合您的情況,因爲您不必處理異常值數據。

我的猜測是,你觀察到的問題來自於模式選擇:

  • 是3分
  • 並且添加了三角形

的重心,但在我看來,它或多或少類似於僅使用3點,因爲您添加的第4點是三角形的重心,並且不應在姿態估計問題中提供任何其他信息。

關於3點(P3P)的姿態估計問題,最多有四種可能的解決方案,並且可以使用第4個點去除歧義。關於這方面的一些參考:

我的建議是使用4個正方形的形狀,而不是和測試,看看你是否觀察同樣的問題(P3P標誌應該沒問題)。如果是,則代碼或校準中存在問題。

這裏的一篇文章我認爲或多或少與問題相關:Why is the Danger Cylinder Dangerous in the P3P Problem?。該圖的情況下,鏈接不可用:

Danger cylinder

+0

感謝您的答覆。其實,是的,你是對的,因爲我的問題解決了,當我再增加一點時。 提示:CV_P3P我在第一旋轉矢量鏈中有奇怪的輪廓,所有其他角度看起來不錯。用CV_EPNP解決。 – vmkan