opencv KNN 模型不能保存的问题
由Opencv 機器學習部分在線文檔
?http://docs.opencv.org/modules/ml/doc/ml.html
得知,這些機器學習方法K-Nearest Neighbors等都繼承于基類CvStatModel,此基類中有save,load等方法,http://wiki.opencv.org.cn/index.php/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E4%B8%AD%E6%96%87%E5%8F%82%E8%80%83%E6%89%8B%E5%86%8C#CvStatModel?中文解釋說save,load方法會調用write和read方法。
在早期opencv中,基類的load和save都是純虛函數,即子類要加以實現。
class CvStatModel { public:/* CvStatModel(); *//* CvStatModel( const CvMat* train_data ... ); */virtual ~CvStatModel();virtual void clear()=0;/* virtual bool train( const CvMat* train_data, [int tflag,] ..., const CvMat* responses, ...,[const CvMat* var_idx,] ..., [const CvMat* sample_idx,] ...[const CvMat* var_type,] ..., [const CvMat* missing_mask,] <misc_training_alg_params> ... )=0;*//* virtual float predict( const CvMat* sample ... ) const=0; */virtual void save( const char* filename, const char* name=0 )=0;virtual void load( const char* filename, const char* name=0 )=0;virtual void write( CvFileStorage* storage, const char* name )=0;virtual void read( CvFileStorage* storage, CvFileNode* node )=0; };而后來opencv對此做了修改,修改成為了虛函數。如下:
class CV_EXPORTS_W CvStatModel { public:CvStatModel();virtual ~CvStatModel();virtual void clear();CV_WRAP virtual void save( const char* filename, const char* name=0 ) const;CV_WRAP virtual void load( const char* filename, const char* name=0 );virtual void write( CvFileStorage* storage, const char* name ) const;virtual void read( CvFileStorage* storage, CvFileNode* node );protected:const char* default_model_name; };這個虛函數聲明說明,任何繼承自CvStatModel的類都可以調用save,load等。
但是在使用KNN時調用save會出錯,我們查看ml.hpp 文件發現opencv中K-Nearest Neighbors沒有實現load,save,write,read這些函數。如下:
// k Nearest Neighbors class CV_EXPORTS_W CvKNearest : public CvStatModel { public:CV_WRAP CvKNearest();virtual ~CvKNearest();CvKNearest( const CvMat* trainData, const CvMat* responses,const CvMat* sampleIdx=0, bool isRegression=false, int max_k=32 );virtual bool train( const CvMat* trainData, const CvMat* responses,const CvMat* sampleIdx=0, bool is_regression=false,int maxK=32, bool updateBase=false );virtual float find_nearest( const CvMat* samples, int k, CV_OUT CvMat* results=0,const float** neighbors=0, CV_OUT CvMat* neighborResponses=0, CV_OUT CvMat* dist=0 ) const;CV_WRAP CvKNearest( const cv::Mat& trainData, const cv::Mat& responses,const cv::Mat& sampleIdx=cv::Mat(), bool isRegression=false, int max_k=32 );CV_WRAP virtual bool train( const cv::Mat& trainData, const cv::Mat& responses,const cv::Mat& sampleIdx=cv::Mat(), bool isRegression=false,int maxK=32, bool updateBase=false );virtual float find_nearest( const cv::Mat& samples, int k, cv::Mat* results=0,const float** neighbors=0, cv::Mat* neighborResponses=0,cv::Mat* dist=0 ) const;CV_WRAP virtual float find_nearest( const cv::Mat& samples, int k, CV_OUT cv::Mat& results,CV_OUT cv::Mat& neighborResponses, CV_OUT cv::Mat& dists) const;virtual void clear();int get_max_k() const;int get_var_count() const;int get_sample_count() const;bool is_regression() const;virtual float write_results( int k, int k1, int start, int end,const float* neighbor_responses, const float* dist, CvMat* _results,CvMat* _neighbor_responses, CvMat* _dist, Cv32suf* sort_buf ) const;virtual void find_neighbors_direct( const CvMat* _samples, int k, int start, int end,float* neighbor_responses, const float** neighbors, float* dist ) const;protected:int max_k, var_count;int total;bool regression;CvVectors* samples; };此時如果用KNN.save時會調用基類的虛函數,而我們無法知道基類的save是如何實現的。
而在可以保存的svm等方法中發現了,read和write的聲明
// SVM model class CV_EXPORTS_W CvSVM : public CvStatModel { public:// SVM typevirtual void write( CvFileStorage* storage, const char* name ) const;virtual void read( CvFileStorage* storage, CvFileNode* node );我們這里省略了大部分,可猜測不同的方法保存是有差別的。
我們沒有在KNN代碼中找到任何實現write和read的函數,通過運行出錯,我們理解為opencv并沒有實現對knn的write,這是源于knn的特點的,knn所謂的train也是只是保存樣本數據,沒有生成分類的模型,這個train函數也不是嚴格意義的訓練。
如果我們想保存這些樣本數據,可以通過保存樣本特征在文件中,一次讀入,可以參考http://www.aishack.in/2010/10/k-nearest-neighbors-in-opencv/
?
總結
以上是生活随笔為你收集整理的opencv KNN 模型不能保存的问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 两个排序数组合并第k或前k个最小值问题
- 下一篇: Vs2010 MFC 简单制作过程中的