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

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,599 times

Last updated: Apr 10 '15