Adaptive non maximal suppression for keypoints distribution Java?

asked 2016-07-29 03:59:30 -0500

gi gravatar image

Hi, I'm sorry to ask but I'm new to OpenCV for Android, and I've tried to change this code on the last answer to Java. The questions are:

  1. I don't understand sort function. Is that from library? If it's not how should I make it?
  2. Is the numeric_limits I set myself? If yes, what number should I set it to?
  3. Core.norm( keypoints.get(i).pt - keypoints.get(j).pt ) Java can't substract Point with Point. I've tried Point temp = new Point(keypoints.get(i).pt.x - keypoints.get(j).pt.x, keypoints.get(i).pt.y - keypoints.get(j).pt.y) but the Core.norm need Mat parameter.
  4. swap function on the bottom?

The code that I change

public void adaptiveNonMaximalSuppresion( List<KeyPoint> keypoints,
                                   const int numToKeep )
{
    if( keypoints.size() < numToKeep ) { return; }

    //
    // Sort by response
    //

    //sort( keypoints.begin(), keypoints.end(), 
    //[&]( const cv::KeyPoint& lhs, const cv::KeyPoint& rhs )
    //{
    //    return lhs.response > rhs.response;
    //} );

    List<KeyPoint> anmsPts = new ArrayList<KeyPoint>();

    List<Double> radii = new ArrayList<Double>();
    //radii.resize( keypoints.size() );
    List<Double> radiiSorted = new ArrayList<Double>();
    //radiiSorted.resize( keypoints.size() );

    Float robustCoeff = 1.11f; // see paper

    for( int i = 0; i < keypoints.size(); ++i )
    {
        Float response = keypoints.get(i).response * robustCoeff;
        Double radius = numeric_limits<Double>::max();
        for( int j = 0; j < i && keypoints[j].response > response; ++j )
        {
            radius = Math.min( radius, Core.norm( keypoints.get(i).pt - keypoints.get(j).pt ) );
        }
        radii.set(i,radius);
        radiiSorted.set(i,radius);
    }

    //std::sort( radiiSorted.begin(), radiiSorted.end(),
    //[&]( const double& lhs, const double& rhs )
    //{
    //    return lhs > rhs;
    //} );

    Double decisionRadius = radiiSorted.get(numToKeep);
    for( int i = 0; i < radii.size(); ++i )
    {
        if( radii.get(i) >= decisionRadius )
        {
            anmsPts.add( keypoints.get(i) );
        }
    }

    anmsPts.swap( keypoints );
}
edit retag flag offensive close merge delete

Comments

Instead of trying to translate the code from one language to another, you should 1) read the paper mentioned from the original answer to your question (and perhaps relevant papers cited by that paper), 2) make sure understand the method/algorithm, 3) verify that the offered C++ code is doing what it claims to do 4) implement the method yourself in Java, using the C++ code only as a guide when you are stuck on specifics. The algorithm is not complicated, it is a very simple, if slightly clever, idea. You should be able to do it for yourself from nothing but the paper.

Der Luftmensch gravatar imageDer Luftmensch ( 2016-12-23 18:29:28 -0500 )edit

@gi Alternatively, you can just use SSC algorithm with Java implementation available.

Dail gravatar imageDail ( 2020-07-24 10:50:46 -0500 )edit