Как получить правильное вращение из разложенного гомографии в OpenCV - PullRequest
0 голосов
/ 07 ноября 2019

Я использовал возможности обнаружения признаков OpenCV, чтобы найти свой объект (страницу книги) в камере и вычислил матрицу гомографии. После этого я использовал DedeposeHomographyMat (), чтобы вычислить вращение объекта следующим образом:

vector<Mat> R, T, N;
decomposeHomographyMat(H, getCameraMatrix(frameWidth, frameHeight), R, T, N);


Mat getCameraMatrix(int width, int height) {
    Mat mat = Mat(3, 3, cv::DataType<double>::type);
    mat.at<double>(0, 0) = width;
    mat.at<double>(0, 1) = 0;
    mat.at<double>(0, 2) = width / 2;
    mat.at<double>(1, 0) = 0;
    mat.at<double>(1, 1) = height;
    mat.at<double>(1, 2) = height / 2;
    mat.at<double>(2, 0) = 0;
    mat.at<double>(2, 1) = 0;
    mat.at<double>(2, 2) = 1;
    return mat;
}

DeposeHomographyMat () возвращает 4 возможные матрицы вращения, которые я уменьшаю до 2, отбрасывая те с отрицательным z в соответствующихвектор перевода.

После этого я вычисляю углы Эйлера (рыскание, наклон, крен), используя следующую функцию:

Mat getEulerAngles(Mat& rotMatrix) {

    Mat ret(1, 3, cv::DataType<double>::type);
    double r31 = rotMatrix.at<double>(2, 0);
    double r32 = rotMatrix.at<double>(2, 1);
    double r33 = rotMatrix.at<double>(2, 2);
    double r21 = rotMatrix.at<double>(1, 0);
    double r11 = rotMatrix.at<double>(0, 0);

    double thetaY = -asin(r31) * 180 / PI;
    double thetaX = atan2(r32, r33) * 180 / PI;
    double thetaZ = atan2(r21, r11) * 180 / PI;

    ret.at<double>(0, 0) = thetaX;
    ret.at<double>(0, 1) = thetaY;
    ret.at<double>(0, 2) = thetaZ;

    return ret;
}

кажется, что оба решения дают правильные значения крена, но не такдля рыскания и тангажа. В частности, для решения 1 рыскание и тангаж верны, если объект вращается в одном направлении (например, вверх или влево), и неверны, когда вращается в противоположном направлении (вниз или вправо). Второе решение работает противоположным образом с правильными результатами в том направлении, где решение 1 было неправильным и неправильным, когда решение 1. было правильным.

Итак, мне нужны оба варианта, но как я могу проверить, когда использовать правильную матрицу.

...