自己对CBIR比较感兴趣,cbir中很重要的一个环节就是特征提取。这里分享一下不错的一些代码。
这里首先是几个用的比较多的与特征相关的C++类。
1、BaseFeature
最根本的一个类,今后用到的所有特征类都派生(或间接派生)于它。
class BaseFeature { protected: FeatureType type_; public: BaseFeature() :type_(FT_BASE) {} virtual ~BaseFeature() {} virtual BaseFeature *clone() const=0; const FeatureType& type() const { return type_;} FeatureType& type() { return type_;} virtual bool load(const ::std::string &filename); virtual void save(const ::std::string &filename); virtual bool read(::std:: istream & is)=0; virtual bool readBinary(::std:: istream &){ERR << "Not supported for this featuretype." <<::std::endl; return true;} // CHANGE virtual void write(::std::ostream & os)=0; virtual void writeBinary(::std::ostream &) {ERR << "Not supported for this featuretype." <<::std::endl;} virtual const unsigned long int calcBinarySize() const { return 0;} BaseFeature & operator-=(const BaseFeature &){ ERR << "not implemented" << std::endl; return (*this); } // this is necessary for da factory template<class T> static BaseFeature* create() { return new T(); } };
2、VectorFeature类
在cbir中,特征提取出以后都是以向量的形式被使用的。这个类直接派生与BaseFeature是非常重要的一个。
class VectorFeature : public BaseFeature { protected: ::std::vector<double> data_; public: VectorFeature() : data_() {type_=FT_VEC;} VectorFeature(uint size) : data_(size) {type_=FT_VEC;} VectorFeature(const ::std::vector<double> &in) : data_(in) {type_=FT_VEC;} virtual VectorFeature* clone() const { return new VectorFeature(*this); } virtual ~VectorFeature() {} VectorFeature operator-(const VectorFeature &v ) const; VectorFeature & operator-=(const VectorFeature &v ); virtual bool read(::std:: istream & is); virtual bool readBinary(::std:: istream & is); virtual void write(::std::ostream & os); virtual void writeBinary(::std::ostream & os); virtual double operator[](uint idx) const { return data_[idx];} virtual double& operator[](uint idx) { return data_[idx];} virtual const uint size() const; virtual const unsigned long int calcBinarySize() const; virtual ::std::vector<double> & data() {return data_;} virtual const ::std::vector<double> & data() const {return data_;} };
3、ImageFeature
这是派生于VectorFeature,使用最为广泛的一个。其定义为
class ImageFeature : public VectorFeature { protected: uint xsize_, ysize_, zsize_; ::std::vector< ::std::vector<double> > data_; #ifdef HAVE_IMAGE_MAGICK /// convert the image to the data structure used by image /// magick. This is needed for saving and displaying of images. Magick::Image makeMagickImage(const uint &idx1=0, const uint &idx2=1, const uint& idx3=2) const; #else #warning "no makeMagickImage without ImageMagick" #endif public: /*------------------------------------------------------------ Constructor/Destructor ------------------------------------------------------------*/ /// do nothing constructor ImageFeature(); ImageFeature(uint xsize, uint ysize,uint zsize); ImageFeature(const ::std::vector<double> &vec, uint x, uint y, uint z=1) { xsize_=x; ysize_=y; zsize_=z; data_.resize(z); for(uint c=0;c<z;++c) { data_[c].resize(x*y); for(uint x=0;x<xsize_;++x) { for(uint y=0;y<ysize_;++y) { data_[c][y*xsize_+x]=vec[y*xsize_*zsize_+x*zsize_+c]; } } } } /// deconstruct image virtual ~ImageFeature(); virtual ImageFeature *clone() const {return new ImageFeature(*this);} /*------------------------------------------------------------ Loading/Saving ------------------------------------------------------------*/ virtual bool load(const ::std::string &filename); virtual bool load(const ::std::string& filename, bool forceGray); virtual void save(const ::std::string& filename) {save(filename,0,1,2);} virtual void save(const ::std::string& filename, const uint& idx1, const uint& idx2, const uint& idx3); virtual bool read(::std::istream & is); virtual bool readBinary(::std::istream & is); virtual void write(::std::ostream & os); virtual void writeBinary(::std::ostream & os); virtual void createFromJF(DoubleVector* imageData); virtual DoubleVector* toJF(int channel = 0); virtual void createFromPixelset(int width, int height, int* pixels); virtual void createFromPixelset(int width, int height, const ::std::vector<int>& pixels); virtual void display(const uint& idx1=0, const uint& idx2=1, const uint& idx3=2) const; /*------------------------------------------------------------ Access to the data ------------------------------------------------------------*/ virtual const uint size() const { return xsize_*ysize_*zsize_;} virtual const unsigned long int calcBinarySize() const; virtual const uint xsize() const { return xsize_;} virtual const uint ysize() const { return ysize_;} virtual const uint zsize() const { return zsize_;} virtual double operator[](uint idx) const { return data_[idx%zsize_][idx/zsize_];} virtual double& operator[](const uint idx) { return data_[idx%zsize_][idx/zsize_];} virtual const ::std::vector<double> operator()(uint x, uint y) const; virtual double& operator()(uint x, uint y, uint c) { return data_[c][y*xsize_+x];} virtual const double& operator()(uint x, uint y, uint c) const { return data_[c][y*xsize_+x];} virtual void append(const ImageFeature& img); virtual const ImageFeature layer(const uint i) const; HSVPixel hsvPixel(int x, int y); ::std::string& filename() {return filename_;} const ::std::string& filename() const {return filename_;} virtual ::std::vector<double> layerVector(const uint i) const {return data_[i];} virtual void resize(const uint width, const uint height, const uint depth) { xsize_=width; ysize_=height; zsize_=depth; data_.resize(zsize_); for(uint c=0;c<zsize_;++c) { data_[c].resize(xsize_*ysize_); } } private: ::std::string filename_; };