J'ai une tâche assez simple: obtenir des angles d'Euler d'un triangle planaire. Motif ressemble thissolvePNP pour triangle planaire
Ainsi, l'algorithme:
1) obtenir une image de webcam - fait
2) convertir gryascale, filtre, etc. - fait
3) obtenir centres de masse de tous les composants connectés, et les filtrer - fait. Ce qui ressemble à this. Les cercles rouges décrivent les centres de masse des sommets des triangles.
codeest assez simple, mais la voici:
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) j'appelle solvePNP pour obtenir la rotation & vecteurs de traduction
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 est déclarée comme std::vector<cv::Point3f> m_origin;
et rempli valeurs (mesurées en 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 est déclaré std::vector<cv::Point2f> m_imagePoints;
et contient les coordonnées en pixels des centres de masse (cercles rouges sur le deuxième écran).
Et j'obtenir des résultats assez étranges: this-that
Qu'ai-je essayé et ça ne m'a pas aidé:
1) utilisé double et flotter dans les types m_cameraMatrix, m_distMatrix, m_rvec, m_tvec
2) réarrangés points dans m_origin
3) joué avec solvePnPRansac et ses paramètres d'entrée
4) joué avec les méthodes PnP: itérative et epnp
5) useExtrinsicGuess = true - il aide, mais parfois la solution est "bloquée" et donne des valeurs complètement faux (mille degrés dans le vecteur de rotation)
Et J'ai plusieurs questions:
1) est-ce que l'ordre d'origine et les points d'image sont importants? Comme mentionné here, parfois c'est le cas, mais c'était il y a un an.
2) est-ce que ma tâche peut être résolue d'une autre manière que d'utiliser solvePnP?
Merci. J'apprécierais toute aide!
Merci pour votre réponse. En fait, oui, vous aviez raison, parce que mon problème a été résolu, quand j'ai ajouté un point de plus. Un indice de plus: avec CV_P3P j'ai des contours étranges dans la première chaîne de vecteur de rotation, tous les autres angles semblaient bons. Résolu avec CV_EPNP. – vmkan