看了一些数字识别的文章,研究了一翻得到一些心得,这里就不保留完全写上来!
博主原来做游戏辅助也有数字识别,当时用的是特征码技术,这种技术识别2D的数字还是非常准确的,因为2D游戏数字像素点很纯,比如字体是纯白色,然后R,G,B都是255,那我只取255,255,255指定区域的所有像素,然后生成一个数字特征码,比如0就是"62226"表示0,"02810"表示1,"43333"表示2,这个特征码就是图片像素的宽和高中取得对应坐标的白色像素点。
但如果用于有锯齿或者有渐变的游戏数字就识别不了了,因为这个针对性太强了,一对一。不过也不怕,也有解决方案。我们可以把数字二值化,然后取得各数字的像素和,0~9的像素和各不一样,后期就按这个像素和来判断是哪个数字。这种方法不仅高效,而且准确性也相当不错。当然前提是字体和大小都一样,如果不一样的话,那肯定也不自然不准了。
思想就这些,实现方法百度一查就一大堆,我这里就不写了。几十行代码的事儿!
博主原来做游戏辅助也有数字识别,当时用的是特征码技术,这种技术识别2D的数字还是非常准确的,因为2D游戏数字像素点很纯,比如字体是纯白色,然后R,G,B都是255,那我只取255,255,255指定区域的所有像素,然后生成一个数字特征码,比如0就是"62226"表示0,"02810"表示1,"43333"表示2,这个特征码就是图片像素的宽和高中取得对应坐标的白色像素点。
但如果用于有锯齿或者有渐变的游戏数字就识别不了了,因为这个针对性太强了,一对一。不过也不怕,也有解决方案。我们可以把数字二值化,然后取得各数字的像素和,0~9的像素和各不一样,后期就按这个像素和来判断是哪个数字。这种方法不仅高效,而且准确性也相当不错。当然前提是字体和大小都一样,如果不一样的话,那肯定也不自然不准了。
思想就这些,实现方法百度一查就一大堆,我这里就不写了。几十行代码的事儿!
void COpenCv::IdenNumer(void) { //数字识别流程处理,方案:首先二值化取出所有的数字,然后切割每个一数字, //求每个数字的像素平方和(就是所有像素总和)去对应模板数字的总和,相差最小的应该就是对应的数字了 IplImage* src = cvLoadImage("20131112221252453.png",CV_LOAD_IMAGE_GRAYSCALE);//CV_LOAD_IMAGE_GRAYSCALE加载灰度图 //对大于dThreshold的像素值进行截断,大于dThreshold则为255,不大于dThreshold的为原值 cvThreshold(src,src,0,255,CV_THRESH_OTSU);//二值化处理CV_THRESH_OTSU适用于局部颜色色差大 //接下来找到轮廓 CvMemStorage *pStore = cvCreateMemStorage();//创建一个内存存储器 CvSeq *pOut = NULL;//CvSeq本身就是一个可增长的序列,不是固定的序列 cvFindContours(src,pStore,&pOut,sizeof(CvContour),CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE);//从二值位图找轮廓 //cvFindContours(img,pStore,&pOut,sizeof(CvContour),CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); //填充所有轮廓 cvDrawContours(src, pOut, CV_RGB(255,255,255),CV_RGB(255,255,255), 2, CV_FILLED, 8, cvPoint(0, 0)); vector<Mimg> vec; while(pOut) { CvRect rect = cvBoundingRect(pOut,0); //绘制出每个数字的轮廓 //cvRectangle(src, cvPoint(rect.x, rect.y), cvPoint(rect.x + rect.width, rect. // y + rect.height),CV_RGB(255,255,255), 1, 1, 0); cvSetImageROI(src,rect); IplImage* dst = cvCreateImage(cvSize(rect.width,rect.height),src->depth,src->nChannels); cvCopy(src,dst); cvResetImageROI(src); Mimg img = {rect,dst}; vec.push_back(img); pOut = pOut->h_next;//下一个值 } //这里按坐标从左到右排序 std::sort(vec.begin(),vec.end(),SortFunc);//排序 for (vector<Mimg>::iterator it=vec.begin();it!=vec.end();it++) { //从左右到识别 } cvReleaseMemStorage(&pStore); pStore = NULL; //cvShowImage("",src); cvReleaseImage(&src); }
收藏的用户(0) X
正在加载信息~
推荐阅读
最新回复 (0)
站点信息
- 文章2313
- 用户1336
- 访客11685158
每日一句
Do small things greatly.
把小事做到伟大。
把小事做到伟大。
新会员