Get angles from pose OpenCV (display a video on top of homography)

asked 2019-07-30 05:07:06 -0600

AntersBear gravatar image

I have a simple OpenCV program that tries to find a particular image in the camera and if it finds it, it computes its homography. This part is working perfectly. I now want to display a video onto this homography in Javascript / HTML. To do this, I need to compute the angle (x,y,z), as well as the size and position of the of the video to put on the homography.

For the sizing, I figured I could do this by averaging the distances between the 4 points from the homography horizontally and vertically / or using the max values. For the position, I was just going to find the average and thus center of the 4 points. Please let me know if this is a good idea on how to do this?

For the angles, this seems a bit more complicated. I found that I could estimate the pose with a script like this. And then display it in HTML like this. The only thing is I'm not actually sure how to get the angles in degrees from the pose?

Any help / advice about this would be much appreciated. Please feel free to give code / pseudo in any language of your preference such as C++, Python, JS, etc... My program is written in OpenCV.js but I realize it's a pretty obscure platform so anything will do.

What my homography stuff looks like

var objF1 = new cv.Point2fVector();
var sceneF1 = new cv.Point2fVector();
var HF1 = new cv.Mat();
[HF1, objF1, sceneF1] = getHomography(obj, scene); // OBJ + SCENE COME FROM DMATCHVECTOR AFTER RATIO TEST

var x1, x2, x3, x4;
[x1,x2,x3,x4] = getPoints(HF1);

Some of the helper functions

// FIND HOMOGRAPHY & FIND MATCHES WITHIN HOMOGRAPHY MASK
function getHomography(obj, scene) {
    var filteredObj = new cv.Point2fVector();
    var filteredScene = new cv.Point2fVector();

    var H = new cv.Mat();
    var mask = new cv.Mat();

    H = cv.findHomographyEasyMask(obj, scene, cv.FM_RANSAC, 3.0, mask);

    for (let i = 0; i < obj.size(); i++) {
        if (mask.data[i] == 1) {
            filteredObj.push_back(obj.get(i));
            filteredScene.push_back(scene.get(i));
        }
    }

    mask.delete();

    return [H, filteredObj, filteredScene];
}

// TRANSFORM PERSPECTIVE AND GET POINTS
function getPoints(H) {
    var obj_corners_mat = new cv.Mat(4, 1, cv.CV_32FC2);
    var scene_corners_mat = new cv.Mat(4, 1, cv.CV_32FC2);

    var view = obj_corners_mat.data32F;
    view[0] = 0;
    view[1] = 0;
    view[2] = img1Raw.cols;
    view[3] = 0;
    view[4] = img1Raw.cols;
    view[5] = img1Raw.rows;
    view[6] = 0;
    view[7] = img1Raw.rows;

    cv.perspectiveTransform(obj_corners_mat, scene_corners_mat, H);

    var dataAns = scene_corners_mat.data32F;

    var x1 = [dataAns[0], dataAns[1]];
    var x2 = [dataAns[2], dataAns[3]];
    var x3 = [dataAns[4], dataAns[5]];
    var x4 = [dataAns[6], dataAns[7]];

    obj_corners_mat.delete();
    scene_corners_mat.delete();

    return [x1, x2, x3, x4];
}
edit retag flag offensive close merge delete