Ask Your Question

DutchMark's profile - activity

2018-05-17 05:19:52 -0500 received badge  Famous Question (source)
2017-08-01 05:26:35 -0500 received badge  Popular Question (source)
2016-01-13 09:02:42 -0500 received badge  Self-Learner (source)
2016-01-13 09:02:36 -0500 received badge  Student (source)
2015-09-22 12:02:04 -0500 received badge  Notable Question (source)
2014-11-01 16:41:10 -0500 received badge  Popular Question (source)
2013-05-22 19:30:58 -0500 asked a question DescriptorMatcher::set() crashes in iOS, it's fine in OS X.

I have code that creates a detector, extractor and matcher based on parameters it gets passed. Unfortunately it crashes in iOS while executing the set() function to set the parameters, like in the following snippet:

  const string BRUTE_FORCE("BruteForce");
  const string NORM_TYPE("normType");
  ...
  cv::Ptr<DescriptorMatcher> _descriptorMatcher = DescriptorMatcher::create( matcherType );
    if (_descriptorMatcher.empty())
        cout << "No matcher: " << matcherType.c_str() << endl;
    if (!matcherType.compare(BRUTE_FORCE))
        _descriptorMatcher->set(NORM_TYPE,NORM_HAMMING);

For OSX it works fine however. Same for the FeatureDetector, after calling FeatureDetector::create() any call to the set() method crashes with the debugger showing EXC_BAD_ACCESS(code=1, address=0x0)

Does anyone know why this happens?

2013-05-21 20:11:01 -0500 commented answer What are the SURF support restrictions?

I tried this with another project. Unfortunately, the quality of the matches is much lower using ORB so it's not an option for me.

2013-05-20 16:39:51 -0500 answered a question findHomography problems

I found that getting this all to work is more of an art than a science. One thing that stands out to me is that you don't check how many items you have in good_matches. findHomography() will cause an error if you pass less than 4 points. So you should at least put an if (good_matches.size()>=4) somewhere in there.

In my opinion there's also a bug in FlannBasedMatcher, as the call matcher.match( descriptors_object, descriptors_scene, matches ); should actually be matcher.match( descriptors_scene, descriptors_object, matches ); if you trust the documentation. Except that it would give terrible results.

2013-05-16 17:25:30 -0500 commented question Difference between flann based matcher in C and C++?

I found a mistake that overstated the result. Rather than finding three times as many good matches it's actually one-and-half times as many. Still a very big difference and still the same problem with training. I have edited the original post to improve it.

2013-05-16 14:46:32 -0500 commented question Difference between flann based matcher in C and C++?

It's true it's a bit of a mix of C and C++. The flann part is pretty much a straight copy of the flannFindPairs() function from the find_object.cpp sample code in openCV. I call it the C version because it uses CvSeq, IplImage and cvExtractSURF rather than their C++ counterparts. When I do as you suggest, indeed the results are much better than FlannBasedMatcher. I have added a test3() function to show it. This makes me wonder if I'm using the FlannBasedMatcher in the wrong way (but then, so do all the examples I found on the web) and I tried reversing the parameters descriptors1 and descriptors2 in the knnMatch() call. Interestingly, that gave me the exact same bad results as using the (commented) lines of code using the train() function. Something seriously wrong with FlannBasedMatcher?

2013-05-15 21:09:20 -0500 asked a question Difference between flann based matcher in C and C++?

I'm trying to use the C++ version of the flann based matcher, mainly so I can train it for several pictures ahead of time. The results however are not very satisfactory. As a little test I made a program with two implementations, one using the C API and the other using the C++ API. For some reason the C implementation finds 50% more good matches than the C++ version. And when I use the train() function, the results are even worse. Not only is the number of good matches even lower, the quality of the matches is also a lot worse. (Which becomes obvious when I draw them.)

It seems the difference must be with the flann code, as the number of SURF descriptors generated by either method are equal.

The (standalone) code is below. I also attached the images I used to test this here: C:\fakepath\Cow.jpg C:\fakepath\Test.jpg

Any explanation of the different results would be greatly appreciated.

#include <stdio.h>
#include <iostream>
#include <cv.hpp>

#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/nonfree/features2d.hpp"

using namespace cv;
using namespace std;

#define HESSIAN_VALUE 1500
#define THRESHOLD 0.6

void readme();

int test1(int argc, char *argv[])
{
    Mat img_1 = imread( argv[1], IMREAD_GRAYSCALE );
    Mat img_2 = imread( argv[2], IMREAD_GRAYSCALE );

    vector<KeyPoint> keypoints1;
    Mat descriptors1;
    vector<KeyPoint> keypoints2;
    Mat descriptors2;

    vector< vector< DMatch >  > matches;
    vector< DMatch > good_matches;

    SurfFeatureDetector detector(HESSIAN_VALUE);
    detector.detect(img_1, keypoints1);
    detector.detect(img_2, keypoints2);
    SurfDescriptorExtractor extractor;
    extractor.compute(img_1, keypoints1, descriptors1);
    extractor.compute(img_2, keypoints2, descriptors2);
    FlannBasedMatcher flannMatcher (new cv::flann::KDTreeIndexParams(4), new cv::flann::SearchParams(64));
//    vector<Mat> descriptorList;
//    descriptorList.push_back(descriptors1);
//    flannMatcher.add(descriptorList);
//    flannMatcher.train();
//    flannMatcher.knnMatch(descriptors2, matches, 2);
    flannMatcher.knnMatch(descriptors1, descriptors2, matches, 2);

    for (int i = 0; i < keypoints1.size(); ++i)
    {
        if (matches[i].size() < 2)
            continue;

        const DMatch &m1 = matches[i][0];
        const DMatch &m2 = matches[i][1];

        if (m1.distance <= THRESHOLD * m2.distance)
            good_matches.push_back(m1);
    }
    std::cout << "1- matches found: " << good_matches.size() << std::endl;
    std::cout << "1- descriptors1 found: " << descriptors1.size() << std::endl;
    std::cout << "1- descriptors2 found: " << descriptors2.size() << std::endl;
    Mat img_matches;
    drawMatches( img_1, keypoints1, img_2, keypoints2, good_matches, img_matches );
    imshow("Matches", img_matches );
    return 0;
}

int test2(int argc, char *argv[])
{
    IplImage* img_1 = cvLoadImage( argv[1], CV_LOAD_IMAGE_GRAYSCALE );
    IplImage* img_2 = cvLoadImage( argv[2], CV_LOAD_IMAGE_GRAYSCALE );

    CvSeq * keypoints1 = 0;
    CvSeq * descriptors1 = 0;
    CvSeq * keypoints2 = 0;
    CvSeq * descriptors2 = 0;

    CvMemStorage* storage = cvCreateMemStorage(0);
    CvSURFParams params = cvSURFParams(HESSIAN_VALUE, 1);
    cvExtractSURF( img_1, 0, &keypoints1, &descriptors1, storage, params );
    cvExtractSURF( img_2, 0, &keypoints2, &descriptors2, storage, params );

    int length = (int)(descriptors1->elem_size/sizeof(float));

    cv::Mat m_object(descriptors1->total, length, CV_32F);
    cv::Mat m_image(descriptors2->total, length, CV_32F);

    vector<int> good_matches;

    // copy descriptors
    CvSeqReader obj_reader;
    float* obj_ptr = m_object.ptr<float>(0);
    cvStartReadSeq( descriptors1, &obj_reader );
    for(int i = 0; i < descriptors1->total; i++ )
    {
        const float* descriptor = (const float*)obj_reader.ptr;
        CV_NEXT_SEQ_ELEM( obj_reader.seq->elem_size, obj_reader );
        memcpy(obj_ptr, descriptor, length*sizeof(float));
        obj_ptr += length;
    }
    CvSeqReader img_reader;
    float* img_ptr = m_image.ptr ...
(more)
2013-04-22 15:38:15 -0500 received badge  Editor (source)
2013-04-22 15:37:04 -0500 answered a question What are the SURF support restrictions?

I finally figured out what was the problem. It turned out to be the order in which the libraries were linked. When I moved libopencv_nonfree.a to the front of the list of libraries it suddenly worked.

No need for the inclusion of "opencv2/features2d/features2d.hpp" and "opencv2/nonfree/nonfree.hpp". The former is already included through cv.hpp, the purpose of the latter is purely to include "opencv2/features2d/features2d.hpp" and declare cv::initModule_nonfree(). But there's no need for any call to cv::initModule_nonfree(), maybe that's an obsolete requirement?

2013-04-22 14:10:39 -0500 commented answer What are the SURF support restrictions?

OK, I tried it out just now and it didn't solve the problem. I still get the same message. The method where it gets stuck is this: CV_IMPL void cvExtractSURF( const CvArr* _img, const CvArr* _mask, CvSeq* _keypoints, CvSeq* _descriptors, CvMemStorage* storage, CvSURFParams params, int useProvidedKeyPts) { . . . Ptr<Feature2D> surf = Algorithm::create<Feature2D>("Feature2D.SURF"); if( surf.empty() ) CV_Error(CV_StsNotImplemented, "OpenCV was built without SURF support"); . . .

which is in 'modules/src/legacy/features2d.hpp'.

Would I need to do something for it to use 'nonfree/features2d.hpp'? If so, how? (I did add the include statements you recommended)

Apologies for the formatting.

2013-04-21 16:49:52 -0500 commented answer What are the SURF support restrictions?

Thanks for the answer, I'm going to try it out on Monday. I already have BUILD_opencv_nonfree set and libopencv_nonfree.a is buing built, but I didn't know the cv::initModule_nonfree() call was required. When I link it with dynamic libraries it does not require it, nor the include statements you mention.

With regards to the patent, when the time comes this application will be commercialized we'll make sure we're not violating anything or get the appropriate license. I was under the understanding though that algorithms can't be patented, only specific applications using it. But being in the software business ourselves we're more than willing to pay for work by others, provided the cost is reasonable.

2013-04-19 21:33:08 -0500 asked a question What are the SURF support restrictions?

I made a nice application to find matching features in photos. I noticed however that the libraries are not included when I build the application, which makes it difficult to give it to other people.

So I managed to build the app with static libraries that I built from source (originally I used MacPorts to install opencv). But during run-time it tells me that SURF support was not compiled in.

The exact message I get is this:

OpenCV Error: The function/feature is not implemented (OpenCV was built without SURF support) in cvExtractSURF, file /Users/mboon/Documents/workspaceGit/opencv-2.4.5/modules/legacy/src/features2d.cpp, line 77

So I looked around the web to solve that and ran into a few things. One was a suggestion that I needed to include the nonfree library. But I already do that and I still get the message that SURF is disabled. The libopencv_nonfree.a file is 1.5Mb but I don't really know what's in there.

The other thing I saw is that the reason SURF is not included by default since version 2.4 due to patent or import restrictions. Can anyone point me to information about what those restrictions are? Can I actually use it, or not? Would I need a license?

Can someone tell me what exactly I'd need to do to build OpenCV including SURF support? Is there a CMake option I missed? Something else?

Any information or help is greatly appreciated.