Ask Your Question

Revision history [back]

Feature Detection Module output not matching with Optimization mode Enabled

Hi all,

I'm working with 3D Reconstruction module and I'm using Feature detector output as an Input for our module. I'm using opencv 4.0 for Feature detection module. If we disable the optimization the output is changing to the order of 10-4 and this is affecting our output across different platforms.

Is this a known issue? Is there any known work around for this? Any insights on the major module causing the difference is much appreciated.

I've investigated the major function inside this AKAZE algorithm and found that convolution is taking 60% of the computation time, I've checked the bit exactness of the convolution and it is bit-matching with and without the optimization.

#include "opencv2/opencv.hpp"
#include "opencv2/features2d.hpp"
#include <iostream>
#include <Windows.h>
#include <stdlib.h>

#include "Utility.h"

using namespace std;
using namespace cv;

static void Compare_Keypoints(const std::vector<cv::KeyPoint> KeyPoint1, const  std::vector<cv::KeyPoint> KeyPoint2, const double EPSILON)
{
    using namespace cv;
    bool bStatus = true;
    uint16_t NoofErrors = 0;
    KeyPoint Max_Diff;
    Max_Diff.pt = Point2f(0.0, 0.0);
    Max_Diff.angle = 0;
    Max_Diff.class_id = 0;
    Max_Diff.octave = 0;

    for (size_t i = 0; i < KeyPoint1.size(); i++)
    {
        KeyPoint KP_P1 = KeyPoint1[i];
        KeyPoint KP_P2 = KeyPoint2[i];

        KeyPoint KP_Diff;
        KP_Diff.pt = KP_P1.pt - KP_P2.pt;
        KP_Diff.size = KP_P1.size - KP_P2.size;
        KP_Diff.angle = KP_P1.angle - KP_P2.angle;
        KP_Diff.response = KP_P1.response - KP_P2.response;
        KP_Diff.octave = KP_P1.octave - KP_P2.octave;
        KP_Diff.class_id = KP_P1.class_id - KP_P2.class_id;

        if ((abs(KP_Diff.pt.x)> EPSILON) || (abs(KP_Diff.pt.y)> EPSILON) ||
            (abs(KP_Diff.size)> EPSILON) || (abs(KP_Diff.angle)> EPSILON) ||
            (abs(KP_Diff.response)> EPSILON) || (abs(KP_Diff.octave)> EPSILON) ||
            (abs(KP_Diff.class_id)> EPSILON))
        {
            NoofErrors++;
            bStatus = false;

            Max_Diff.pt.x = max(KP_Diff.pt.x, Max_Diff.pt.x);
            Max_Diff.pt.y = max(KP_Diff.pt.y, Max_Diff.pt.y);
            Max_Diff.angle = max(KP_Diff.angle, Max_Diff.angle);
            Max_Diff.response = max(KP_Diff.response, Max_Diff.response);
            Max_Diff.size = max(KP_Diff.size, Max_Diff.size);
        }
    }

    if (NoofErrors == 0)
        std::cout << "[Passed] : No Errors Found \n" << std::endl;
    else
    {
        std::cout << format("[Error] : %d Errors Found\n", NoofErrors);
        std::cout << cv::format("KeyPoint Max Diff: Pt [ %f , %f ] , Angle : %f , Response : %f \n", Max_Diff.pt.x, Max_Diff.pt.y, Max_Diff.angle, Max_Diff.response, Max_Diff.size);

    }

}

static void Compare_Descriptors(const cv::Mat Mat1, const cv::Mat Mat2, const double EPSILON)
{
    using namespace cv;
    cv::Mat AbsDiff;
    cv::absdiff(Mat1, Mat2, AbsDiff);
    cv::threshold(AbsDiff, AbsDiff, 0, EPSILON, THRESH_TOZERO);

    uint32_t NonZero = cv::countNonZero(AbsDiff);
    if (NonZero)
    {
        std::cout << cv::format("[Error] : %d Errors Found in Descriptors\n", NonZero);
        double Min, Max;
        cv::minMaxLoc(AbsDiff, &Min, &Max);
        std::cout << cv::format("Descriptors Max Error : %f \n", Max);
    }
    else
        std::cout << "[Passed] : No Errors Found \n\n" << std::endl;

}

int main()
{
    CreateDirectoryW(L"Dumps/",NULL);

    Mat mSrc = imread("D:\\Valeo\\Project_Files\\Softwares\\OpenCV\\OpenCV_4.0\\samples\\data\\baboon.jpg", 0);
    Ptr<AKAZE> akaze = AKAZE::create(cv::AKAZE::DESCRIPTOR_KAZE_UPRIGHT,2,1,0.00005,5,3,1);

    std::vector<cv::KeyPoint> KeyPoints_CV;
    cv::Mat Descriptors_CV;

    std::vector<cv::KeyPoint> KeyPoints_CV_Opt;
    cv::Mat Descriptors_CV_Opt;

    KeyPoints_CV.clear();
    Descriptors_CV.release();

    cv::setUseOptimized(false);
    akaze->detectAndCompute(mSrc, noArray(), KeyPoints_CV, Descriptors_CV);

    cv::setUseOptimized(true);
    akaze->detectAndCompute(mSrc, noArray(), KeyPoints_CV_Opt, Descriptors_CV_Opt);

    if (KeyPoints_CV.size())//Not Relevent 
        cv::drawKeypoints(mSrc, KeyPoints_CV, mSrc, cv::Scalar(0, 255, 0));

    Compare_Keypoints(KeyPoints_CV, KeyPoints_CV_Opt, DBL_EPSILON);
    Compare_Descriptors(Descriptors_CV, Descriptors_CV_Opt, DBL_EPSILON);

    cv::imshow("Source Image", mSrc);           

    waitKey();
    return 0;
}

Program output:

 [Error] : 3710 Errors Found
    KeyPoint Max Diff: Pt [ 0.000153 , 0.000549 ] , Angle : 0.000061 , Response : 0.000000
    [Error] : 26421 Errors Found in Descriptors
    Descriptors Max Error : 0.000033