您的位置:首页 > 运维架构

Opencv入门教程之使用Opencv进行模式识别与分类

2013-09-15 15:33 796 查看
本章中,主要介绍一些模式识别的基础概念。

在模式识别中,对元素进行分类之前,我们需要采集样本进行训练。本章的实例中,训练了3个类,每一个类采集了100个样本。

对于训练,需要创建两个矩阵,一个是用于存储样本数据的矩阵,一个用于与数据对应的类的标号:

Int train_sample_count=300;//总共300个样本

CvRNG rng_state = cvRNG(-1);

CvMat* trainData =cvCreateMat(train_sample_count,2,CV_32FC1);//存储样本数据

CvMat* trainClasses = cvCreateMat(train_sample_count, 1, CV_32FC1 );//存储类的标号

矩阵trainData是一个有train_sample_count行,2列,该矩阵中的每一行代表一个样本,每一个样本是用一个2维的横向量来表示。矩阵trainClasses有train_sample_count行,1列,

其行数是与trainData相同,trainClasses是与trainData一一对应的,假设trainData中的第一行的样本数据是属于第3类的,那么,trainClasses中第一行的那个值就是3.

在我们的例子中,trainClasses中的前100的样本数据时第一个类的,第100到第200行的样本数据第2类的,最后100行样本数据时第3类的。

那么:

cvGetRows( trainClasses, &trainClasses1, 0, 100 );

cvSet( &trainClasses1, cvScalar(1) );

cvGetRows( trainClasses, &trainClasses2, 100, 200);

cvSet( &trainClasses2, cvScalar(2) );

cvGetRows( trainClasses, &trainClasses3, 200, 300);

cvSet( &trainClasses3, cvScalar(3) );

函数cvGetRows是通过选取原矩阵中的某些行,得到一个新矩阵:

cvGetRows(srcMatrix, destMatrix, first_row, last_row );

那么destMatrix就是srcMatrix的第first_row到第last_row行的矩阵数据。

cvSet是给矩阵赋一个初始值,例如:

cvSet(matrix, cv_scalar_value );是把矩阵matrix中的所有的值设为cv_scalar_value。

本教程中,采用随机数来生成样本,使用的是opencv中的函数cvRandArr,由前面可知,我们的样本是二维的,那么需要由cvRandArr给每一个样本产生2个随机值。

产生训练样本1

cvGetRows( trainData, &trainData1, 0,100 );

cvGetCol( &trainData1, &colData1x, 0);

cvGetCol( &trainData1, &colData1y, 1);

cvRandArr( &rng_state, &colData1x, CV_RAND_NORMAL, cvScalar(200),cvScalar(50) );

cvRandArr( &rng_state, &colData1y, CV_RAND_NORMAL, cvScalar(200),cvScalar(50) );

产生训练样本2

cvGetRows( trainData, &trainData2, 100,200 );

cvGetCol( &trainData2, &colData2x, 0);

cvGetCol( &trainData2, &colData2y, 1);

cvRandArr( &rng_state, &colData2x, CV_RAND_NORMAL, cvScalar(300),cvScalar(50) );

cvRandArr( &rng_state, &colData2y, CV_RAND_NORMAL, cvScalar(300),cvScalar(50) );

产生训练样本3

cvGetRows( trainData, &trainData3, 200, 300 );

cvGetCol( &trainData3, &colData3x, 0);

cvGetCol( &trainData3, &colData3y, 1);

cvRandArr( &rng_state, &colData3x, CV_RAND_NORMAL, cvScalar(100),cvScalar(30) );

cvRandArr( &rng_state, &colData3y, CV_RAND_NORMAL, cvScalar(400),cvScalar(30) );

有了样本数据后,我们就可以进行训练了,在本教程中,使用k近邻域分类器(k nearest neighbour )。这种分类器最简单,而且能实现分多类。它的原理是通过一个投票机制,把目标分类到最近的邻域里。

需要使用opencv的CvKNearest类

CvKNearestknn( trainData, trainClasses, 0, false, K );

第一个参数是训练样本数据,第二个参数是类的标签。

那么现在就得到了一个knn分类器,如果现在需要判断一个二维向量是属于这3个类中的哪一个类,那么只需要调用knn.find_nearest函数就ok了,就会返回类的标签号。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: