机器学习(4)——KNN算法及手写数字的识别(二)

机器学习——KNN算法及手写数字的识别(二)

    说的是手写数字识别,你拿一堆

    

图一

这样的“图片”去识别,分类有什么意思呀。

    在上一遍博文中 机器学习——KNN算法及手写数字的识别(一) 我们有了一个对手写数字采用kNN算法的分类器,这篇博文将利用该分类器完成一个完整的手写数字分类功能。程序的输入为我们手机拍摄的一张照片如下图所示:

    

图 二

    为了使用我们训练好的分类器,我们需要对这张照片进行处理,把图片中的每一个数字处理成图一中的格式。图像实质上就是对空间以及幅度的采样,因此转化为一图中0,1的格式思路也是很明确的。

算法主要流程如下:

1、二值化,彩色图像转化为二值图像


图 三

    2、形态学处理,消除图像中的噪声同时使每个数字更加“饱满”

图 四

3、检测角点并进行聚类,将各个数字分隔

4、将0-1图像转化到32*32尺寸的向量中用于运算

最终结果:




    其中,数字1是由于角点聚类时没有提取1所在的区域,因此没有检测到结果。其他6、8检测错误其余检测正确。可以看到,简单的kNN也是能基本达到识别手写数字的需求的。

     主要代码:

     1、预处理

     

vector<pair<Mat,Point>> numImageCut(string fileName)
{
	vector<pair<Mat,Point>> imgList;

	Mat srcImg = imread(fileName,0);
	resize(srcImg, srcImg, Size(srcImg.cols / 4, srcImg.rows / 4));
	getBinaryImage(srcImg,srcImg);
	imshow("src", srcImg);

	
	imshow("binaryimg", srcImg);


	//dilate(srcImg, srcImg, Mat(), Point(-1, -1), 1);
	erode(srcImg, srcImg, Mat(), Point(-1, -1), 1);		// 腐蚀:黑色区域增大 [3/7/2015 pan]
	imshow("erodImg", srcImg);
	dilate(srcImg, srcImg, Mat(),Point(-1,-1),2);

	imshow("dilate",srcImg);
	//waitKey(-1);
	Mat img_contours;
	srcImg.copyTo(img_contours);
	vector<vector<Point>> contours;
	findContours(img_contours, contours, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
	
	
	vector<Rect> rectList = getFigureRect(contours);
	char c = 0;
	for (auto it = rectList.begin(); it != rectList.end(); it++){
		//rectangle(srcImg, *it, Scalar(255), 2);
// 		c++;
// 		Mat figure = srcImg(*it);
// 		imshow("rects" + c, figure);
	}
	imshow("contours", srcImg);
	for (auto it = rectList.begin(); it != rectList.end(); it++){
		Mat figure = srcImg(*it);
		Point pt(it->x, it->y);
		resize(figure, figure, Size(32, 32));
		imgList.push_back(make_pair(figure,pt));
	}
	
	return imgList;
	
}

     2、角点聚类,提取包含数字的字图片

     

vector<Rect>  getFigureRect(vector<vector<Point>>& contours)
{
	vector<Rect> rectList;
	vector<int> vecSizeList;
	for (auto it = contours.begin(); it != contours.end(); it++){
		vecSizeList.push_back(it->size());
	}
	// K均值聚类:得到两个类别(数字上的角点,非数字上的角点) [3/7/2015 pan]

	vector<int> figureIndex = kMeansClsssify(vecSizeList, 3);

	for (auto it = figureIndex.begin(); it != figureIndex.end(); it++){
		Rect rect = minAreaRect(contours[*it]).boundingRect();		// boundingRect:returns the minimal up-right rectangle containing the rotated rectangle [3/7/2015 pan]
		rect.x -= 2;
		rect.y -= 2;
		rect.width += 2;
		rect.height += 2;
		rectList.push_back(rect);
	}

	return rectList;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值