Handwritten digit recognition "QT+OPENCV"

Source: Internet
Author: User

Description

Handwritten digital recognition is implemented in many ways.

This article simplifies it as much as possible so that you can quickly understand how to implement a moving system.

【】




Ideas

1. Feature Extraction

Divides the image into an area of 5*5 size, and then calculates the percentage of pixels in black (or white) within that region.

Feature extraction is performed for images that need to be tested, and for classifying images.

2. Calculate the Euclidean distance between the current test image and the image used to classify it.

3. Finding the minimum Euclidean distance is the image that best matches the current test image, and the number represented by the image is the result of the current test image.

4. In order to deal with the convenience, the simplified treatment is as follows:

4.1 Select only 10 images to classify.

In practical applications, 10 images are far from enough. But in order to simplify the program, only 10 images are used here, that is, the digital 0~9 each number only chooses one feature.

In the actual system, when the feature image is selected, the accuracy of the system becomes higher.

4.2 uses the nearest neighbor. That is, the selection of the smallest European distance image as the result of the current test image.

In the actual system, it is often necessary to use K nearest neighbor, that is, choose the smallest k Euclidean distance, determine which class they belong to and determine the current numerical results.

For reasons of simplification, the correct rate of digital recognition is not very high. But the basic ability to meet the learning needs.

"Partial Code"

The system was developed using QT+OPENCV and some of the codes are as follows:

"Main intra-class variable and slot function"

Public:    Explicit MainWindow (Qwidget *parent = 0);    ~mainwindow ();    Cv::mat testimage,srcimage[10],tempimage;//testimage value to test the digital image, Srcimage refers to the existing digital Image qimage IMG To achieve the classification    ;    Float testfeature[25];//The array is used to store the eigenvalues of the digital image to be detected.    The float srcfeature[10][25];//is used to store the eigenvalues of the original digital image. Only 10 digital 0~9 images    void getfeature (Cv::mat m,float a[25]);//This defines a function that acquires image features.    float oudistance (float a[25],float b[25]);    Float odistance (float a[25],float b[25]);p rivate slots:         void on_openlenajpg_triggered ();         void On_exitsystem_triggered ();         void On_opencustomefile_triggered ();         void On_restorefile_triggered ();         void On_copyright_triggered ();         void On_about_triggered ();         void On_showimage_triggered ();         void On_showmessage_triggered ();         void On_imageandmessage_triggered ();

"Open a custom path for the image to be measured"

void Mainwindow::on_opencustomefile_triggered () {QString filename = qfiledialog::getopenfilename (this,tr ("Open Image    ")," ", tr (" Image File (*.bmp *.jpg *.jpeg *.png) ");    Qtextcodec *code = Qtextcodec::codecforname ("GB18030");    std::string name = Code->fromunicode (filename). data ();    Testimage = Cv::imread (name);        if (!testimage.data) {Qmessagebox msgBox;        Msgbox.settext (TR ("Data not Found"));    Msgbox.exec ();        } else {cv::cvtcolor (TESTIMAGE,TESTIMAGE,CV_BGR2RGB); img = qimage ((const unsigned char*) (testimage.data), Testimage.cols,testimage.rows, testimage.cols*        Testimage.channels (), qimage::format_rgb888);        Ui->label1->clear ();        Img= img.scaled (Ui->label1->width (), Ui->label1->height ());        Ui->label1->setpixmap (Qpixmap::fromimage (IMG));        Ui->processpushbutton->setenabled (TRUE); Ui->label1->resize (Ui->label1->pixmap ()->size ());//Set the current label to image size//Ui->labeL1->resize (Img.width (), Img.height ());    This->setwidget (Label1); }}

"Image feature Extraction: Complete the image 5*5=25 features, each feature represents the number of white pixels in the sub-region"

void Mainwindow::getfeature (Cv::mat m,float a[25]) {int m,n;    The wide-height int i,j used to store the image m;    M=m.cols;    N=m.rows;    for (i=0;i<25;i++) a[i]=0; Qmessagebox::information (NULL, "Title", Qstring::number (m.at<uchar> (188,88)), Qmessagebox::yes |    Qmessagebox::no, Qmessagebox::yes);   for (i=0;i<m;i++) for (j=0;j<n;j++) if (m.at<uchar> (i,j) ==255) {//   a[i/5*5+j/5]++; Here the error is calculated and cannot be placed in the corresponding eigenvalues//qmessagebox::information (NULL, "Title", Qstring::number (5), Qmessagebox::yes | Q                Messagebox::no, Qmessagebox::yes);                a[m/i*5+n/j]++;                a[m/(i+1) *5+n/(j+1)]++;                a[i/(M/5) *5+j/(N/5)]++; Qmessagebox::information (NULL, "Title", "Add", Qmessagebox::yes |            Qmessagebox::no, Qmessagebox::yes);  } for (i=0;i<25;i++) {//Qmessagebox::information (NULL, "Title", Qstring::number (A[i]), Qmessagebox::yes | Qmessagebox::no, Qmessagebox:: Yes);        a[i]=a[i]/((M/5) * (N/5)); Qmessagebox::information (NULL, "Title", Qstring::number (A[i]), Qmessagebox::yes |        Qmessagebox::no, Qmessagebox::yes); Qmessagebox::information (NULL, "Title", Qstring::number (5), Qmessagebox::yes |    Qmessagebox::no, Qmessagebox::yes); }//Qmessagebox::information (NULL, "Title", Qstring::number (A[5]), Qmessagebox::yes | Qmessagebox::no, Qmessagebox::yes);}

"Euclidean distance calculation, the second function is for testing"

Float mainwindow::oudistance (float a[25],float b[25])   //This function actually forgot to write MainWindow class relationship, debugging for a long time, waterfall sweat! {    int i;    Float distance=0;//start to forget zero, Error!!! For    (i=0;i<25;i++)        distance+= (A[i]-b[i]) * (A[i]-b[i]);    DISTANCE=SQRT (distance);    return distance;} float  mainwindow::odistance (float a[25],float b[25])   //This function is tested when oudistance problem, and is not used {    int i;    float distance=0;   Start to forget to reset the zero, Error!!!    //, in order to test the oudistance function, rewrite the odistance discovery problem, and the result is again the problem has been modified in this function. The calling function is also oudistance for    (i=0;i<25;i++)        distance+= (A[i]-b[i]) * (A[i]-b[i]);    DISTANCE=SQRT (distance);    return distance;}

Description

void Mainwindow::on_copyright_triggered () {    qmessagebox::information (this, "copyright", tr ("copyright owner of the software: Tianjin Vocational and technical Normal University. If used, please contact: lilizong#gmail "));} void Mainwindow::on_about_triggered () {    qmessagebox::information (this, "about", tr ("The current version of the software is 1.0, developed by people such as Li Lizong. If there is a problem, please contact: lilizong#gmail "));    return;}




"Show test results: An image, an information box"

void mainwindow::on_imageandmessage_triggered () {int i; float min;   Used to store the smallest Euclidean distance int mini;    The numeric number used to store the minimum Euclidean distance.   Getfeature (testimage,testfeature);    Gets the characteristic value of the test image and places it inside the testfeature array. Qmessagebox::information (NULL, "Title", Qstring::number (Testfeature[6]), Qmessagebox::yes |    Qmessagebox::no, Qmessagebox::yes); Tests whether the current testfeature is normal/* for (i=0;i<25;i++) qmessagebox::information (NULL, "Title", Qstring::number (Testfeatu Re[i]), Qmessagebox::yes | Qmessagebox::no, Qmessagebox::yes); *//Qmessagebox::information (NULL, "Title", Qstring::number (Testimage.rows), Qmessagebox::yes |    Qmessagebox::no, Qmessagebox::yes);        for (i=0;i<10;i++) {QString filepath,filename,allname;    Filepath= "image\\stand\\";       Current image directory Filename= ". bmp";  The current image has the extension allname=filepath+ "\ \" +qstring::number (i) +filename;    I is the file name, using Qstring::number (i) to finish converting it to the qstring type, which is currently a numeric String s=allname.tostdstring ();   Convert to standard string type, Imread does not recognize qstring type     Srcimage[i] = Cv::imread (s);    }//The following section is used to test whether the above code can get the value of Srcimage.    /* Cv::cvtcolor (SRCIMAGE[3],SRCIMAGE[3],CV_BGR2RGB); img = qimage ((const unsigned char*) (srcimage[3].data), Srcimage[1].cols,srcimage[1].rows, srcimage[1].cols*srcimage[    1].channels (), qimage::format_rgb888);    Ui->label1->clear ();    Img= img.scaled (Ui->label1->width (), Ui->label1->height ());    Ui->label1->setpixmap (Qpixmap::fromimage (IMG)); *//Get the eigenvalues of the original digital image.    for (i=0;i<10;i++) getfeature (Srcimage[i],srcfeature[i]); /* for (i=0;i<25;i++) qmessagebox::information (NULL, "Title", Qstring::number (Srcfeature[0][i]), qmess Agebox::yes |  Qmessagebox::no, Qmessagebox::yes);   */float oudistancevalue[10]={0};        Stores the Euclidean distance between the current test image and a known 10 Digital image for (i=0;i<10;i++) {oudistancevalue[i]=oudistance (testfeature,srcfeature[i]);    Oudistancevalue[i]=i;    }//always can not get results, test under oudistance there is no problem. /* for (i=0;i<10;i++) QmessagEbox::information (NULL, "Title", Qstring::number (Oudistancevalue[i]), Qmessagebox::yes |    Qmessagebox::no, Qmessagebox::yes);    */mini=0;  MIN=OUDISTANCEVALUE[0];    Assign an initial value to min, assuming the distance to the number 0 is minimal.            for (i=0;i<10;i++) {if (Min>oudistancevalue[i]) {min=oudistancevalue[i];        Mini=i; }}//Qmessagebox::information (NULL, "Title", Qstring::number (mini), Qmessagebox::yes |    Qmessagebox::no, Qmessagebox::yes);    The above statement tests if the mini can get the correct value//the image that matches the current test image is displayed in Label2 cv::cvtcolor (SRCIMAGE[MINI],SRCIMAGE[MINI],CV_BGR2RGB); img = qimage ((const unsigned char*) (srcimage[mini].data), Srcimage[mini].cols,srcimage[mini].rows, Srcimage[mini].    Cols*srcimage[mini].channels (), qimage::format_rgb888);    Ui->label2->clear ();    Img= img.scaled (Ui->label2->width (), Ui->label2->height ());    Ui->label2->setpixmap (Qpixmap::fromimage (IMG)); Displays the matching results of the current image in a message box Qmessagebox::information (NULL, "test result", "the recognition result of the current test image is a number:" +qsTring::number (mini), Qmessagebox::yes | Qmessagebox::no, Qmessagebox::yes);}



Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Handwritten digit recognition "QT+OPENCV"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.