opencv7-ml之KNN

准备知识
在文件”opencv\sources\modules\ml\src\precomp.hpp“中
有cvPrepareTrainData的函数原型。

int
cvPrepareTrainData( const char* /*funcname*/,
                    const CvMat* train_data, int tflag,
                    const CvMat* responses, int response_type,
                    const CvMat* var_idx,
                    const CvMat* sample_idx,
                    bool always_copy_data,
                    const float*** out_train_samples,
                    int* _sample_count,
                    int* _var_count,
                    int* _var_all,
                    CvMat** out_responses,
                    CvMat** out_response_map,
                    CvMat** out_var_idx,
                    CvMat** out_sample_idx=0 )

从函数原型的参数可以看出主要为:
const char* /funcname/: 函数的名称
const CvMat* train_data, int tflag,: 训练集、训练集样本的布局
const CvMat* responses, int response_type,:训练集标签、对应数据类型
const CvMat* var_idx,: 用了哪些特征
const CvMat* sample_idx,: 用了哪些样本
bool always_copy_data,: 是否复制数据集
const float*** out_train_samples,: 输出处理过的的训练集
int* _sample_count, : 样本的总数
int* _var_count,: 特征的总数
int* _var_all,
CvMat** out_responses,: 输出训练集标签
CvMat** out_response_map,
CvMat** out_var_idx, : 输出用了哪些特征
CvMat** out_sample_idx=0 : 默认输出为使用了所有的样本

在文件”opencv\sources\modules\ml\src\inner_functions.cpp“中有cvPrepareTrainData的函数实现:

int
cvPrepareTrainData( const char* /*funcname*/,
                    const CvMat* train_data, int tflag,
                    const CvMat* responses, int response_type,
                    const CvMat* var_idx,
                    const CvMat* sample_idx,
                    bool always_copy_data,
                    const float*** out_train_samples,
                    int* _sample_count,
                    int* _var_count,
                    int* _var_all,
                    CvMat** out_responses,
                    CvMat** out_response_map,
                    CvMat** out_var_idx,
                    CvMat** out_sample_idx )
{
    int ok = 0;//用于标记该函数是否成功执行
    CvMat* _var_idx = 0;//默认使用所有的特征
    CvMat* _sample_idx = 0;//默认使用所有的样本
    CvMat* _responses = 0;
    int sample_all = 0, sample_count = 0, var_all = 0, var_count = 0;

    CV_FUNCNAME( "cvPrepareTrainData" );

    // step 0. clear all the output pointers to ensure we do not try
    // to call free() with uninitialized pointers
    //第0步,先释放所有输出的指针以确保不会有未初始化的指针。
    if( out_responses )
        *out_responses = 0;

    if( out_response_map )
        *out_response_map = 0;

    if( out_var_idx )
        *out_var_idx = 0;

    if( out_sample_idx )
        *out_sample_idx = 0;

    if( out_train_samples )
        *out_train_samples = 0;

    if( _sample_count )
        *_sample_count = 0;

    if( _var_count )
        *_var_count = 0;

    if( _var_all )
        *_var_all = 0;
//重置完成
    __BEGIN__;

    if( !out_train_samples )
        CV_ERROR( CV_StsBadArg, "output pointer to train samples is NULL" );

    CV_CALL( cvCheckTrainData( train_data, tflag, 0, &var_all, &sample_all ));

    if( sample_idx )
        CV_CALL( _sample_idx = cvPreprocessIndexArray( sample_idx, sample_all ));
    if( var_idx )
        CV_CALL( _var_idx = cvPreprocessIndexArray( var_idx, var_all ));

    if( responses )
    {
        if( !out_responses )
            CV_ERROR( CV_StsNullPtr, "output response pointer is NULL" );

        if( response_type == CV_VAR_NUMERICAL )
        {
            CV_CALL( _responses = cvPreprocessOrderedResponses( responses,
                                                _sample_idx, sample_all ));
        }
        else
        {
            CV_CALL( _responses = cvPreprocessCategoricalResponses( responses,
                                _sample_idx, sample_all, out_response_map, 0 ));
        }
    }

    CV_CALL( *out_train_samples =
                cvGetTrainSamples( train_data, tflag, _var_idx, _sample_idx,
                                   &var_count, &sample_count, always_copy_data ));

    ok = 1;

    __END__;
//如果上面的操作都结束了,那么检测对应的输出需要的指针,是否已经初始化,然后接着对各自的输出指针指向的对象进行置0初始化
    if( ok )
    {
        if( out_responses )
            *out_responses = _responses, _responses = 0;

        if( out_var_idx )
            *out_var_idx = _var_idx, _var_idx = 0;

        if( out_sample_idx )
            *out_sample_idx = _sample_idx, _sample_idx = 0;

        if( _sample_count )
            *_sample_count = sample_count;

        if( _var_count )
            *_var_count = var_count;

        if( _var_all )
            *_var_all = var_all;
    }
    else
    {
        if( out_response_map )
            cvReleaseMat( out_response_map );
        cvFree( out_train_samples );
    }

    if( _responses != responses )
        cvReleaseMat( &_responses );
    cvReleaseMat( &_var_idx );
    cvReleaseMat( &_sample_idx );

    return ok;//返回该函数是否成功执行
}

首先在文件“opencv\sources\modules\ml\include\opencv2\ml\ml.hpp”中有:

#define CV_TYPE_NAME_ML_KNN     "opencv-ml-knn"
struct CvVectors
{
    int type;
    int dims, count;
    CvVectors* next;
    union
    {
        uchar** ptr;
        float** fl;
        double** db;
    } data;
};

/*********K-Nearest Neighbour Classifier **********/

class CV_EXPORTS_W CvKNearest : public CvStatModel
{
public:

    CV_WRAP CvKNearest();//默认构造函数
    virtual ~CvKNearest();//虚析构函数
//2个重载的构造函数,参数中一个是CvMat,一个是Mat
//trainData:训练集
//responses:训练集的目标值
//sampleIdx:用来指定使用哪些训练样本,0表示使用所有的训练样本
//isRegression:trueb表示knn作为回归,否则为分类器
//max_k:K的上限
    CvKNearest( const CvMat* trainData, const CvMat* responses,
                const CvMat* sampleIdx=0, bool isRegression=false, int max_k=32 );

    CV_WRAP CvKNearest( const cv::Mat& trainData, const cv::Mat& responses,
               const cv::Mat& sampleIdx=cv::Mat(), bool isRegression=false, int max_k=32 );
//训练模型,两个重载函数,一个使用的是CvMat;一个使用的是Mat;Mat的会调用CvMat的train实现训练功能。
//updateBase:用于指定该模型是从头开始训练?(update_base=false),还是使用新的训练数据来进行更新
//(update_base=true).在后者中,参数maxK不能大于原始的值
         virtual bool train( const CvMat* trainData, const CvMat* responses,
                        const CvMat* sampleIdx=0, bool is_regression=false,
                        int maxK=32, bool updateBase=false );

    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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值