ocr.h头文件
ocr.cpp
训练的样子,可以自己做.也可以用这篇文章里面的例子opencv 写的 OCR
#pragma once
#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/ml/ml.hpp>
class COcr
{
public:
COcr(void);
~COcr(void);
float classify(IplImage* img,int showResult);//将图片进行分类,得到最终结果
void test();
private:
char file_path[255];
int train_samples;//单个特征码数量,如0,1各有10个特征码
int classes;//分类器数 数字0~9(10个)字母a~z(26个)
CvMat* trainData;
CvMat* trainClasses;
int contourSize;//轮廓大小,统一放大或缩小样本大小为该值(正方形)
static const int K=10;
CvKNearest *knn;
void getData();
/*****************************************************************
*
* Find the min box. The min box respect original aspect ratio image
* The image is a binary data and background is white.
*
*******************************************************************/
void findX(IplImage* imgSrc,int* min, int* max){
int i;
int minFound=0;
CvMat data;
CvScalar maxVal=cvRealScalar(imgSrc->width * 255);
CvScalar val=cvRealScalar(0);
//For each col sum, if sum < width*255 then we find the min
//then continue to end to search the max, if sum< width*255 then is new max
for (i=0; i< imgSrc->width; i++){
cvGetCol(imgSrc, &data, i);
val= cvSum(&data);
if(val.val[0] < maxVal.val[0]){
*max= i;
if(!minFound){
*min= i;
minFound= 1;
}
}
}
}
void findY(IplImage* imgSrc,int* min, int* max){
int i;
int minFound=0;
CvMat data;
CvScalar maxVal=cvRealScalar(imgSrc->width * 255);
CvScalar val=cvRealScalar(0);
//For each col sum, if sum < width*255 then we find the min
//then continue to end to search the max, if sum< width*255 then is new max
for (i=0; i< imgSrc->height; i++){
cvGetRow(imgSrc, &data, i);
val= cvSum(&data);
if(val.val[0] < maxVal.val[0]){
*max=i;
if(!minFound){
*min= i;
minFound= 1;
}
}
}
}
CvRect findBB(IplImage* imgSrc){
CvRect aux;
int xmin, xmax, ymin, ymax;
xmin=xmax=ymin=ymax=0;
findX(imgSrc, &xmin, &xmax);
findY(imgSrc, &ymin, &ymax);
aux=cvRect(xmin, ymin, xmax-xmin, ymax-ymin);
return aux;
}
IplImage* preprocessing(IplImage* imgSrc,int new_width, int new_height){
IplImage* result;
IplImage* scaledResult;
CvMat data;
CvMat dataA;
CvRect bb;//bounding box
//CvRect bba;//boundinb box maintain aspect ratio
//Find bounding box
bb=findBB(imgSrc);
//Get bounding box data and no with aspect ratio, the x and y can be corrupted
cvGetSubRect(imgSrc, &data, cvRect(bb.x, bb.y, bb.width, bb.height));
//Create image with this data with width and height with aspect ratio 1
//then we get highest size betwen width and height of our bounding box
int size=(bb.width>bb.height)?bb.width:bb.height;
result=cvCreateImage( cvSize( size, size ), 8, 1 );
cvSet(result,CV_RGB(255,255,255),NULL);
//Copy de data in center of image
int x=(int)floor((float)(size-bb.width)/2.0f);
int y=(int)floor((float)(size-bb.height)/2.0f);
cvGetSubRect(result, &dataA, cvRect(x,y,bb.width, bb.height));
cvCopy(&data, &dataA, NULL);
//Scale result
scaledResult=cvCreateImage( cvSize( new_width, new_height ), 8, 1 );
cvResize(result, scaledResult, CV_INTER_NN);
//Release
cvReleaseImage(&result);
//Return processed data
return scaledResult;
}
};ocr.cpp
#include "StdAfx.h"
#include "Ocr.h"
IplImage* imagen;
IplImage* screenBuffer;
int drawing;
int r,last_x, last_y;
void draw(int x,int y){
//Draw a circle where is the mouse
cvCircle(imagen, cvPoint(x,y), r, CV_RGB(0,0,0), -1, 4, 0);
//Get clean copy of image
screenBuffer=cvCloneImage(imagen);
cvShowImage( "Demo", screenBuffer );
}
void drawCursor(int x, int y){
//Get clean copy of image
screenBuffer=cvCloneImage(imagen);
//Draw a circle where is the mouse
cvCircle(screenBuffer, cvPoint(x,y), r, CV_RGB(0,0,0), 1, 4, 0);
}
/*************************
* Mouse CallBack
* event:
* #define CV_EVENT_MOUSEMOVE 0
* #define CV_EVENT_LBUTTONDOWN 1
* #define CV_EVENT_RBUTTONDOWN 2
* #define CV_EVENT_MBUTTONDOWN 3
* #define CV_EVENT_LBUTTONUP 4
* #define CV_EVENT_RBUTTONUP 5
* #define CV_EVENT_MBUTTONUP 6
* #define CV_EVENT_LBUTTONDBLCLK 7
* #define CV_EVENT_RBUTTONDBLCLK 8
* #define CV_EVENT_MBUTTONDBLCLK 9
*
* x, y: mouse position
*
* flag:
* #define CV_EVENT_FLAG_LBUTTON 1
* #define CV_EVENT_FLAG_RBUTTON 2
* #define CV_EVENT_FLAG_MBUTTON 4
* #define CV_EVENT_FLAG_CTRLKEY 8
* #define CV_EVENT_FLAG_SHIFTKEY 16
* #define CV_EVENT_FLAG_ALTKEY 32
*
**************************/
void on_mouse( int event, int x, int y, int flags, void* param )
{
last_x=x;
last_y=y;
drawCursor(x,y);
//Select mouse Event
if(event==CV_EVENT_LBUTTONDOWN)
{
drawing=1;
draw(x,y);
}
else if(event==CV_EVENT_LBUTTONUP)
{
//drawing=!drawing;
drawing=0;
}
else if(event == CV_EVENT_MOUSEMOVE && flags & CV_EVENT_FLAG_LBUTTON)
{
if(drawing)
draw(x,y);
}
}
COcr::COcr(void)
{
//initial
sprintf(file_path , "../OCR/");
train_samples = 90;//加载样本越多,速度越慢
classes = 10;
contourSize = 20;
trainData = cvCreateMat(train_samples*classes, contourSize*contourSize, CV_32FC1);
trainClasses = cvCreateMat(train_samples*classes, 1, CV_32FC1);
getData();
knn = new CvKNearest(trainData, trainClasses, 0, false, K);
}
COcr::~COcr(void)
{
if(knn)delete knn;
if(trainData)cvReleaseMat(&trainData);
if(trainClasses)cvReleaseMat(&trainClasses);
}
float COcr::classify(IplImage* img,int showResult)
{
IplImage* prs_image;
CvMat data;
CvMat* nearest = cvCreateMat(1,K,CV_32FC1);
float result;
//process file
prs_image = preprocessing(img, contourSize, contourSize);
//Set data
IplImage* img32 = cvCreateImage(cvSize( contourSize, contourSize ), IPL_DEPTH_32F, 1);
cvConvertScale(prs_image, img32, 0.0039215, 0);
cvGetSubRect(img32, &data, cvRect(0,0, contourSize,contourSize));
CvMat row_header, *row1;
row1 = cvReshape(&data, &row_header, 0, 1);
result = knn->find_nearest(row1,K,0,0,nearest,0);
int accuracy=0;
for(int i=0;i<K;i++){
if( nearest->data.fl[i] == result)
accuracy++;
}
float pre=100*((float)accuracy/(float)K);
if(showResult==1){
DebugString("|\t%.0f\t| \t%.2f%% \t| \t%d of %d \t| \n",result,pre,accuracy,K);
DebugString(" ---------------------------------------------------------------\n");
}
cvReleaseImage(&img32);
cvReleaseImage(&prs_image);
cvReleaseMat(&nearest);
return result;
}
void COcr::getData()
{
IplImage* prs_image;
CvMat row,data;
char file[255];
int i,j;
for(i =0; i<classes; i++){
for( j = 0; j< train_samples; j++){
//Load file
if(j<10)
sprintf(file,"%s%d/%d0%d.pbm",file_path, i, i , j);
else
sprintf(file,"%s%d/%d%d.pbm",file_path, i, i , j);
IplImage* src_image = cvLoadImage(file,0);
if(!src_image){
DebugString("Error: Cant load image %s\n", file);
//exit(-1);
}
//process file
prs_image = preprocessing(src_image, contourSize, contourSize);//原样本图处理指定大小的轮廓图
//Set class label
cvGetRow(trainClasses, &row, i*train_samples + j);
cvSet(&row, cvRealScalar(i));
//Set data
cvGetRow(trainData, &row, i*train_samples + j);
IplImage* img = cvCreateImage(cvSize(contourSize, contourSize), IPL_DEPTH_32F, 1);
//convert 8 bits image to 32 float image
cvConvertScale(prs_image, img, 0.0039215, 0);
cvGetSubRect(img, &data, cvRect(0,0, contourSize,contourSize));
CvMat row_header, *row1;
//convert data matrix sizexsize to vecor
row1 = cvReshape(&data, &row_header, 0, 1);
cvCopy(row1, &row, NULL);
cvReleaseImage(&src_image);
cvReleaseImage(&prs_image);
cvReleaseImage(&img);
}
}
}
void COcr::test()
{
drawing=0;
r=10;
last_x=last_y=0;
//Create image
imagen=cvCreateImage(cvSize(128,128),IPL_DEPTH_8U,1);
//Set data of image to white
cvSet(imagen, CV_RGB(255,255,255),NULL);
//Image we show user with cursor and other artefacts we need
screenBuffer=cvCloneImage(imagen);
//Create window
cvNamedWindow( "Demo", 0 );
cvResizeWindow("Demo", 128,128);
//Create mouse CallBack
cvSetMouseCallback("Demo",&on_mouse, 0 );
//Main Loop
int c = 0;
while(true)
{
cvShowImage( "Demo", screenBuffer );
c = cvWaitKey(10);
if( (char) c == 'x' )
break;
if( (char) c== '+' ){
r++;
drawCursor(last_x,last_y);
}
if( ((char)c== '-') && (r>1) ){
r--;
drawCursor(last_x,last_y);
}
if( (char)c== 'r'){
cvSet(imagen, cvRealScalar(255),NULL);
drawCursor(last_x,last_y);
}
if( (char)c== 's'){
cvSaveImage("out.png", imagen);
}
if( (char)c=='c'){
classify(imagen,1);
}
}
cvDestroyWindow("Demo");
}
训练的样子,可以自己做.也可以用这篇文章里面的例子opencv 写的 OCR
收藏的用户(0) X
正在加载信息~
推荐阅读
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is
最新回复 (1)
-
FrancePvm632973 2017-2-22引用 2楼后来改良了一下图片处理函数,不用到文章提到的CvRect findBB(IplImage* imgSrc)
这个用起来不精确.而且事先要处理一下二值化.
站点信息
- 文章2313
- 用户1336
- 访客11743222
每日一句
Change your thoughts and you change your world.
改变你的想法,你就改变了你的世界。
改变你的想法,你就改变了你的世界。
新会员