opencv的svm学习_字符识别

简介

  这是基于svm实现字符识别,不过只是个大概模板,需要能够准确识别,需要的训练样本太多,没去收集。


代码讲解


具体代码

#include <opencv2/core/core.hpp>                                                                                                   
#include <opencv2/highgui/highgui.hpp>
#include <opencv/cv.h>
#include <stdio.h>
#include <opencv2/ml/ml.hpp>
 
using namespace cv;
 
#define match_all 10
#define match_detect 10
#define pic_size 512
 
int main(int argc, char* argv[]){
	const char *match_pic[match_all] = {
		"rightPic/0.bmp", "rightPic/1.bmp", "rightPic/2.bmp", "rightPic/3.bmp", "rightPic/4.bmp",
		"rightPic/5.bmp", "errorPic/6.bmp", "errorPic/7.bmp", "errorPic/8.bmp", "errorPic/9.bmp",
	};
	int i, j, k;
 
	float labels[10]={1, 1, 1, 1, 1, 1, -1, -1, -1, -1};
	Mat labelsMat(10, 1, CV_32FC1, labels);
 
 
	float trainingData[10][pic_size];
 
	for(i=0; i<match_detect; i++){
		cv::Mat mat1 = cv::imread(match_pic[i], 0);
		uchar* ptr = mat1.ptr(0);
		int length = mat1.rows * mat1.cols;
 
		for(j=0; j<length; j++){
			trainingData[i][j] = (float)ptr[j];
		}	
	}
	Mat trainingDataMat(10, pic_size, CV_32FC1, trainingData);
 
	// Set up SVM's parameters
	CvSVMParams params;
	params.svm_type    = CvSVM::C_SVC;
	params.C            = 0.1; 
	params.kernel_type = CvSVM::LINEAR;
	params.term_crit   = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
 
	// Train the SVM
	CvSVM SVM;
	SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);
 
	cv::Mat mat2 = cv::imread(argv[1], 0);
	uchar* ptr2 = mat2.ptr(0);
	float testData[pic_size];
	for(k=0; k<pic_size; k++){
		testData[k] = (float)ptr2[k];
	}
	cv::Mat mat3(1, pic_size, CV_32FC1, testData);
	float response = SVM.predict(mat3);
	printf("response:%f\n", response);
	cv::imshow("SVM Simple Example", mat2);
 
	waitKey(0);
}


建立训练样本

const char *match_pic[match_all] = {
		"rightPic/0.bmp", "rightPic/1.bmp", "rightPic/2.bmp", "rightPic/3.bmp", "rightPic/4.bmp",
		"rightPic/5.bmp", "errorPic/6.bmp", "errorPic/7.bmp", "errorPic/8.bmp", "errorPic/9.bmp",
	};
	int i, j, k;
 
	float labels[10]={1, 1, 1, 1, 1, 1, -1, -1, -1, -1};
	Mat labelsMat(10, 1, CV_32FC1, labels);
 
 
	float trainingData[10][pic_size];
 
	for(i=0; i<match_detect; i++){
		cv::Mat mat1 = cv::imread(match_pic[i], 0);
		uchar* ptr = mat1.ptr(0);
		int length = mat1.rows * mat1.cols;
 
		for(j=0; j<length; j++){
			trainingData[i][j] = (float)ptr[j];
		}	
	}
	Mat trainingDataMat(10, pic_size, CV_32FC1, trainingData);

  首先是定义使用了10个训练样本,在labels中,利用1和-1,将前6个分为一类,后四个分为一类。接着match_pic定义了训练样本的路径,所谓的训练样本也就是
10张图片,前面6张是字符0的图片,后面4张是其他1-9的图片。这样通过大量训练之后,就能在这个svm中将0从0-9的字符中识别出来。但是训练样本必须大。。不能
如本例这般小。
  分配一个结构保存训练样本数据:trainingData[10][pic_size];将10张16X32的训练图片都导入到该数组中。在本例中,因为训练的样本图片都不大,所以没有取
图片的特征值,而是整个图片导入训练。


训练支持向量机

  // Set up SVM's parameters
	CvSVMParams params;
	params.svm_type    = CvSVM::C_SVC;
	params.C            = 0.1; 
	params.kernel_type = CvSVM::LINEAR;
	params.term_crit   = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
 
	// Train the SVM
	CvSVM SVM;
	SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);

  也是用函数SVM.train用之前填充的trainingDataMat进行训练。


字符识别

 cv::Mat mat2 = cv::imread(argv[1], 0);
	uchar* ptr2 = mat2.ptr(0);
	float testData[pic_size];
	for(k=0; k<pic_size; k++){
		testData[k] = (float)ptr2[k];
	}
	cv::Mat mat3(1, pic_size, CV_32FC1, testData);
	float response = SVM.predict(mat3);
	printf("response:%f\n", response);

  分配mat2来接收,我们需要识别的图片:argv[1],然后一样的使用SVM.predict进行识别。最后如果response 返回为1,表示需要识别的图片是字符0,否则就是0-9
的其他图片。
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值