Ask Your Question
3

BOWKMeansTrainer in Python?

asked 2014-06-07 03:17:23 -0600

peter_trompeter gravatar image

updated 2014-06-07 03:18:48 -0600

Hi all,

I found that BOWKMeansTrainer / BOWImgDescriptorExtractor are not available in the python wrapper ... any special reason for this? I'm using the latest version from github.

Anyway, I checked how the python wrapper is generated, replaced the CV_EXPORTS in the class declarations with CV_EXPORTS_W, rebuilt and now the classes do show up in the generated wrapper code.

Only problem is, python (2.7) still complains that "object has no attribute 'BOWKMeansTrainer'" if I try to instantiate it like bowtrainer = cv2.BOWKMeansTrainer()

So the question is, what am I doing wrong? What is the correct way to expose a class to python? Is this wrapping process documented somewhere?

Thanks in advance Peter

edit retag flag offensive close merge delete

Comments

CV_EXPORTS_W will get your class into pyopencv_generated_types.h, that's fine, yet you need to wrap every method you want exposed with CV_WRAP (including the constructor !).

while you can easily overload functions in c++, try to avoid that in the wrappers, e.g choose only one compute method (or constructor)

last but not least, an obstacle: BOWImgDescriptorExtractor::compute takes pointers to the optional args, that might turn out unusable

berak gravatar imageberak ( 2014-06-07 07:41:34 -0600 )edit

@berak so how do I generate wrappers for BoW functionality and get the required modules to create a fully functional BoW app? Can you enlighten a bit?

bad_keypoints gravatar imagebad_keypoints ( 2014-10-09 09:04:50 -0600 )edit

@bad_keypoints , pr got accepted & merged, so you should be able to use it in 2.4.9 straight away.

here 's a small demo

berak gravatar imageberak ( 2014-10-09 09:10:02 -0600 )edit

@berak that's great! But I'm using 2.4.9 and in the shell, I'm getting the error that cv2 has no such attribute has those functions used in that code in your answer in your link. BTW, I downloaded the 2.4.9 version 5 months ago.

bad_keypoints gravatar imagebad_keypoints ( 2014-10-09 23:58:15 -0600 )edit

"I downloaded the 2.4.9 version 5 months ago." - ah, that explains it. merged 24.6.2014.

you could just update your opencv codebase and recompile, or apply the patches above.

berak gravatar imageberak ( 2014-10-10 01:56:02 -0600 )edit

@berak, also, I suppose the 3.0 alpha would also have the patch? Because it has many more fixes and improvements, so should I just go for the new 3.0?

bad_keypoints gravatar imagebad_keypoints ( 2014-10-10 01:58:55 -0600 )edit

hrrmm, afaik, that was not merged into master branch yet. ;(

berak gravatar imageberak ( 2014-10-10 02:01:28 -0600 )edit

@berak dude I'm not savvy when it comes to make and build stuff. If I download the 2.4.9 zip now, will it have your patch?

bad_keypoints gravatar imagebad_keypoints ( 2014-10-10 02:12:22 -0600 )edit

/me cross thumbs

sure ;)

berak gravatar imageberak ( 2014-10-10 02:24:30 -0600 )edit

@berak. I just finished finally installing 2.4.9 with your patch. But I still don't see cv2.BOWKmeansTrainer or any other methods.

bad_keypoints gravatar imagebad_keypoints ( 2014-10-10 06:12:46 -0600 )edit

github src ? did you do a git checkout 2.4 ? make install too.

berak gravatar imageberak ( 2014-10-10 06:45:01 -0600 )edit

@berak no I didn't. I just cloned the master branch and build it. There was your BOW classes' wrapper but cv2.SVM was missing (not even in cv2.xfeatures2d). I'm seeing your answer late, I'll test it out (2.4 branch). Also, would I need to add the cmake command to include opencv_contrib package to get cv2.SURF and cv2.SVM or will they be available in the core opencv build only?

EDIT: I don't mind using SVM from the 3.0 master branch build. But I don't know where it is. I do see the cv2.ml module, and it has SVM_LINEAR etc, but help() on them shows help on int Python class, so they're not the cv2.SVM as before in 2.4.9 zip build. Can you tell me where I can find SVM class in 3.0 alpha build ? Thanks

bad_keypoints gravatar imagebad_keypoints ( 2014-10-12 23:33:48 -0600 )edit

no, you should not need anything from the contrib repo.

berak gravatar imageberak ( 2014-10-13 00:48:19 -0600 )edit

@berak thanks a tonne man. I checkout the 2.4 branch, everything builds out. SVM, SIFT/SURF, BOW modules. All in one place, finally.

But still though, in the build from the 3.0 alpha release (or the current working master branch on git), where would I find the ML python methods (like SVM()) ? I didn't find anything in cv2.ml or in opencv_contrib modules. And cv2.SVM definitely didn't exist. Just saying, because I'll like to upgrade to 3.0 for all the improvements.

bad_keypoints gravatar imagebad_keypoints ( 2014-10-13 01:53:39 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
6

answered 2014-06-07 09:27:34 -0600

berak gravatar image

updated 2015-04-10 08:31:45 -0600

[edit]: none of this is nessecary any more, BowTrainer and friends are wrapped to python by default now.

this worked for me (with 2.4.9):

(one had to navigate around the BowTrainer constructor and alias the compute method)


class CV_EXPORTS_W BOWTrainer
{
public:
    BOWTrainer();
    virtual ~BOWTrainer();

    CV_WRAP void add( const Mat& descriptors );
    CV_WRAP const vector<Mat>& getDescriptors() const;
    CV_WRAP int descripotorsCount() const;

    CV_WRAP virtual void clear();

    /*
     * Train visual words vocabulary, that is cluster training descriptors and
     * compute cluster centers.
     * Returns cluster centers.
     *
     * descriptors      Training descriptors computed on images keypoints.
     */
    CV_WRAP virtual Mat cluster() const = 0;
    CV_WRAP virtual Mat cluster( const Mat& descriptors ) const = 0;

protected:
    vector<Mat> descriptors;
    int size;
};

/*
 * This is BOWTrainer using cv::kmeans to get vocabulary.
 */
class CV_EXPORTS_W BOWKMeansTrainer : public BOWTrainer
{
public:
    CV_WRAP BOWKMeansTrainer( int clusterCount, const TermCriteria& termcrit=TermCriteria(),
                      int attempts=3, int flags=KMEANS_PP_CENTERS );
    virtual ~BOWKMeansTrainer();

    // Returns trained vocabulary (i.e. cluster centers).
    CV_WRAP virtual Mat cluster() const;
    CV_WRAP virtual Mat cluster( const Mat& descriptors ) const;

protected:

    int clusterCount;
    TermCriteria termcrit;
    int attempts;
    int flags;
};

/*
 * Class to compute image descriptor using bag of visual words.
 */
class CV_EXPORTS_W BOWImgDescriptorExtractor
{
public:
    CV_WRAP BOWImgDescriptorExtractor( const Ptr<DescriptorExtractor>& dextractor,
                               const Ptr<DescriptorMatcher>& dmatcher );
    virtual ~BOWImgDescriptorExtractor();

    CV_WRAP void setVocabulary( const Mat& vocabulary );
    CV_WRAP const Mat& getVocabulary() const;
    void compute( const Mat& image, vector<KeyPoint>& keypoints, Mat& imgDescriptor,
                  vector<vector<int> >* pointIdxsOfClusters=0, Mat* descriptors=0 );
    // compute() is not constant because DescriptorMatcher::match is not constant

    CV_WRAP_AS(compute) void compute2( const Mat& image, vector<KeyPoint>& keypoints, CV_OUT Mat& imgDescriptor )
    { compute(image,keypoints,imgDescriptor); }

    CV_WRAP int descriptorSize() const;
    CV_WRAP int descriptorType() const;

protected:
    Mat vocabulary;
    Ptr<DescriptorExtractor> dextractor;
    Ptr<DescriptorMatcher> dmatcher;
};

>>> be = cv2.BOWImgDescriptorExtractor(None,None)
>>> help(be)
class BOWImgDescriptorExtractor(__builtin__.object)
 ...
 |  compute(...)
 |      compute(image, keypoints, [imgDescriptor]) -> imgDescriptor
 |  descriptorSize(...)
 |      descriptorSize() -> retval
 |  descriptorType(...)
 |      descriptorType() -> retval
 |  getVocabulary(...)
 |      getVocabulary() -> retval
 |  setVocabulary(...)
 |      setVocabulary(vocabulary) -> None

>>> bt = cv2.BOWKMeansTrainer(4)
>>> help(bt)
class BOWKMeansTrainer(BOWTrainer)
 ...
 |  cluster(...)
 |      cluster() -> retval  or  cluster(descriptors) -> retval
 |  ----------------------------------------------------------------------
 |  Methods inherited from BOWTrainer:
 |  add(...)
 |      add(descriptors) -> None
 |  clear(...)
 |      clear() -> None
 |  descripotorsCount(...)
 |      descripotorsCount() -> retval
 |  getDescriptors(...)
 |      getDescriptors() -> retval
 ...
edit flag offensive delete link more

Comments

Nice! Maybe make a pull request? Would be nice...

Guanta gravatar imageGuanta ( 2014-06-08 13:47:28 -0600 )edit
1

that was the plan.

just wondered, why the java bindings were not built, then discovered, that it's avoiding features2d.hpp (in favour of something manually written)

so i'm slightly puzzled, how to get that running. python only solution atm.

berak gravatar imageberak ( 2014-06-08 14:38:12 -0600 )edit

Question Tools

2 followers

Stats

Asked: 2014-06-07 03:17:23 -0600

Seen: 4,506 times

Last updated: Apr 10 '15