用KNN分类器进行数字识别之前的处理
现在我正在尝试使用OpenCV创建数字识别系统。 在WEB中有很多文章和例子(甚至在StackOverflow上)。 我决定使用KNN分类器,因为这种解决方案在WEB中最受欢迎。 我发现了一个手写数字数据库,其中包含60k个示例的训练集,错误率低于5%。
我使用本教程作为如何使用OpenCV处理此数据库的示例。 我使用完全相同的技术和测试数据( t10k-images.idx3-ubyte
),我有4%的错误率。 但是当我尝试对自己的数字进行分类时,我遇到了更大的错误。 例如:
等等(如果需要,我可以上传所有图片)。
正如你所看到的,所有的数字都有很好的质量,并且很容易被人识别。
所以我决定在分类前做一些预处理。 从MNIST数据库网站的表格中我发现人们正在使用去偏移,去噪,模糊和像素移位技术。 不幸的是,几乎所有的文章链接都被打破了。 所以我决定自己做这样的预处理,因为我已经知道如何做到这一点。
现在,我的算法如下:
粗)。
我认为,在我的情况下,不需要纠错,因为所有的数字都是正常旋转的。 而且我也不知道如何找到一个正确的旋转角度。 所以在这之后我得到了这些图像:
所以,这样的预处理对我有点帮助,但是我需要更好的结果,因为在我看来,这些数字应该没有问题地被识别出来。
任何人都可以给我任何意见与预处理? 谢谢你的帮助。
PS我可以上传我的源代码(c ++)。
我意识到自己的错误-它不是在所有前处理连接(感谢@DavidBrown和@约翰 )。 我使用手写数字集而不是打印(大写)。 我没有在网上找到这样的数据库,所以我决定自己创建它。 我已将我的数据库上传到Google云端硬盘。
以下是你如何使用它(训练和分类):
int digitSize = 16;
//returns list of files in specific directory
static vector<string> getListFiles(const string& dirPath)
{
vector<string> result;
DIR *dir;
struct dirent *ent;
if ((dir = opendir(dirPath.c_str())) != NULL)
{
while ((ent = readdir (dir)) != NULL)
{
if (strcmp(ent->d_name, ".") != 0 && strcmp(ent->d_name, "..") != 0 )
{
result.push_back(ent->d_name);
}
}
closedir(dir);
}
return result;
}
void DigitClassifier::train(const string& imagesPath)
{
int num = 510;
int size = digitSize * digitSize;
Mat trainData = Mat(Size(size, num), CV_32FC1);
Mat responces = Mat(Size(1, num), CV_32FC1);
int counter = 0;
for (int i=1; i<=9; i++)
{
char digit[2];
sprintf(digit, "%d/", i);
string digitPath(digit);
digitPath = imagesPath + digitPath;
vector<string> images = getListFiles(digitPath);
for (int j=0; j<images.size(); j++)
{
Mat mat = imread(digitPath+images[j], 0);
resize(mat, mat, Size(digitSize, digitSize));
mat.convertTo(mat, CV_32FC1);
mat = mat.reshape(1,1);
for (int k=0; k<size; k++)
{
trainData.at<float>(counter*size+k) = mat.at<float>(k);
}
responces.at<float>(counter) = i;
counter++;
}
}
knn.train(trainData, responces);
}
int DigitClassifier::classify(const Mat& img) const
{
Mat tmp = img.clone();
resize(tmp, tmp, Size(digitSize, digitSize));
tmp.convertTo(tmp, CV_32FC1);
return knn.find_nearest(tmp.reshape(1, 1), 5);
}
5&6,1&7,9&8被认为是相同的,因为班级的中心点太相似了。 那这个呢 ?
结果,“9”和“8”更容易识别以及“5”和“6”。 上部分相同,但下部分不同。
我不能给你一个比你自己的答案更好的答案,但我想提供建议。 您可以通过以下方式改进您的数字识别系统:
在白色和黑色补丁上应用一个镂空过程 。
之后,应用距离变换。
通过这种方式,当数字不完全居中或者形态上不完全相同时,可以改善分类器的结果。
链接地址: http://www.djcxy.com/p/13973.html上一篇: processing before digit recognition with KNN classifier