lundi 22 octobre 2018

What is the correct way to Normalize corresponding points before estimation of Fundamental matrix in OpenCV C++?

I am trying to manually implement a fundamental matrix estimation function for corresponding points (based on similarities between two images). The corresponding points are obtained after performing ORB feature detection, extraction, matching and ratio test.

There is a lot of literature available on good sources about this topic. However none of them appear to give a good pseudo-code for doing the process. I went through various Chapters on Multiple View Geometry book; and also many online sources.

This source appears to give a formula for doing the normalization and I followed the formula mentioned on page 13 of this source.

Based on this formula, I created the following algorithm. I am not sure if I am doing it the right way though !

Normalization.hpp

class Normalization {
    typedef std::vector <cv::Point2f> intercepts;
    typedef std::vector<cv::Mat> matVec;
public:
    Normalization () {}
    ~Normalization () {}

    void makeAverage(intercepts pointsVec);

    matVec normalize(intercepts pointsVec);

private:
    double xAvg = 0;
    double yAvg = 0;
    double count = 0;
    matVec normalizedPts;
    double distance = 0;
    matVec matVecData;
};

Normalization.cpp

#include "Normalization.hpp"

typedef std::vector <cv::Point2f> intercepts;
typedef std::vector<cv::Mat> matVec;

void Normalization::makeAverage(intercepts pointsVec) {
    count = pointsVec.size();
    for (auto& member : pointsVec) {
        xAvg = xAvg + member.x;
        yAvg = yAvg + member.y;
    }
    xAvg = xAvg / count;
    yAvg = yAvg / count;
}

matVec Normalization::normalize(intercepts pointsVec) {
    for (auto& member : pointsVec) {

        distance = (1 / (count * std::sqrt(2))) *\
                   (std::sqrt(std::pow((member.x - xAvg), 2)\
                              + std::pow((member.y - yAvg), 2)));

        cv::Mat factor = (cv::Mat_<double>(3, 3) << (1 / distance), \
                          0, -(xAvg / distance), 0, (1 / distance), \
                          -(yAvg / distance), 0, (1 / distance), \
                          -(yAvg / distance, 0, 0, 1));

        cv::Mat triplet = (cv::Mat_<double>(3, 1) << member.x, member.y, 1);

        matVecData.emplace_back(factor * triplet);
    }
    return matVecData;
}

Is this the right way ? Are there other ways of Normalization ?

Aucun commentaire:

Enregistrer un commentaire