[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
...
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 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 , pr got accepted & merged, so you should be able to use it in 2.4.9 straight away.
here 's a small demo
@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.
"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, 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?
hrrmm, afaik, that was not merged into master branch yet. ;(
@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?
/me cross thumbs
sure ;)
@berak. I just finished finally installing 2.4.9 with your patch. But I still don't see cv2.BOWKmeansTrainer or any other methods.
github src ? did you do a
git checkout 2.4
?make install
too.@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
no, you should not need anything from the contrib repo.
@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.