Python3 implements simple and learnable handwriting recognition (for example ).

Source: Internet
Author: User

Python3 implements simple and learnable handwriting recognition (for example ).

1. Preface

Version: Python3.6.1 + PyQt5 + SQL Server 2012

I used to think that the machine learning and handwriting recognition programs were very high and difficult until I accidentally saw this video and listened to the teacher's ideas, I instantly felt that this was not so difficult. I still could have done it.

So I started to use Python, PyQt, and SQLServer along the train of thought to see if I could. However, many problems have been encountered in the middle. There are more than a dozen database problems, nearly one hundred PyQt problems, and dozens of basic Python Syntax problems. But fortunately, through continuous Google, we finally come up with such a finished product.

Finally, I restructured the code in a function and changed it into four modules:

Main. py, Learning. py, LearningDB. py, LearningUI. py

LearningDB implements the interaction between python and the database. LearningUI implements the interface interaction. Learning inherits the LearningUI class and adds the interaction with the LearningDB database class. Finally, the main function module runs the program.

For database-related knowledge, refer to the previous article:Python3 Operating SQL Server database (instance description),
For more information about PyQt, see:Python3 use PyQt5 to create a simple canvas/tablet

The main idea of handwriting recognition is to use a list to record the vertices it passes through and divide it into a nine-square lattice, and then count the number of vertices in each grid, converts the number to the percentage of the total number of points. Then the number of nine dimensions stored in the two pairs is calculated as the distance between them. The closer the distance is, the closer the distance is.

2. Interaction with databases through pymssql

Because you need to create a table before using the program, I will directly use the SQL statement to execute the table creation:

create database PyLearningDBdrop table table0create table table0(dim0 int not null,dim1 int not null,dim2 int not null,dim3 int not null,dim4 int not null,dim5 int not null,dim6 int not null,dim7 int not null,dim8 int not null)drop table table1create table table1(dim0 int not null,dim1 int not null,dim2 int not null,dim3 int not null,dim4 int not null,dim5 int not null,dim6 int not null,dim7 int not null,dim8 int not null)drop table table2create table table2(dim0 int not null,dim1 int not null,dim2 int not null,dim3 int not null,dim4 int not null,dim5 int not null,dim6 int not null,dim7 int not null,dim8 int not null)drop table table3create table table3(dim0 int not null,dim1 int not null,dim2 int not null,dim3 int not null,dim4 int not null,dim5 int not null,dim6 int not null,dim7 int not null,dim8 int not null)drop table table4create table table4(dim0 int not null,dim1 int not null,dim2 int not null,dim3 int not null,dim4 int not null,dim5 int not null,dim6 int not null,dim7 int not null,dim8 int not null)drop table table5create table table5(dim0 int not null,dim1 int not null,dim2 int not null,dim3 int not null,dim4 int not null,dim5 int not null,dim6 int not null,dim7 int not null,dim8 int not null)drop table table6create table table6(dim0 int not null,dim1 int not null,dim2 int not null,dim3 int not null,dim4 int not null,dim5 int not null,dim6 int not null,dim7 int not null,dim8 int not null)drop table table7create table table7(dim0 int not null,dim1 int not null,dim2 int not null,dim3 int not null,dim4 int not null,dim5 int not null,dim6 int not null,dim7 int not null,dim8 int not null)drop table table8create table table8(dim0 int not null,dim1 int not null,dim2 int not null,dim3 int not null,dim4 int not null,dim5 int not null,dim6 int not null,dim7 int not null,dim8 int not null)drop table table9create table table9(dim0 int not null,dim1 int not null,dim2 int not null,dim3 int not null,dim4 int not null,dim5 int not null,dim6 int not null,dim7 int not null,dim8 int not null)

The LearningDB. py program is as follows:

'''Learningdb class function: defines the database class, contains a learning function learn_data and an identification function identify_data Author: PyLearn blog: http://www.cnblogs.com/PyLearn/ last modification date: ''' import mathimport pymssqlclass LearningDB (): def _ init _ (self): self. conn = pymssql. connect (host = '2017. 0.0.1 ', user = 'sa', password = '000000', database = 'pylearningdb', charset = 'utf8') self. cursor = self. conn. cursor () self. SQL = ''self. distance = 0.0 self. conn. close () def Learn_data (self, table, dim): ''' learn Data and store the data to the corresponding database table to specify which table. dim is the dimension array ''' learn_result = False try: if table <0 or table> 9: raise Exception ("error! The table value is % d! "% Table) for num in dim: if num <0: raise Exception (" error! The dim value cannot be less than 0! ") Self. conn = pymssql. connect (host = '2017. 0.0.1 ', user = 'sa', password = '000000', database = 'pylearningdb', charset = 'utf8') self. cursor = self. conn. cursor () self. SQL = 'insert into table % d values (% d, % d) '% (table, dim [0], dim [1], dim [2], dim [3], dim [4], dim [5], dim [6], dim [7], dim [8]) self.cursor.exe cute (self. SQL) self. conn. commit () learn_result = True limit t Exception as ex_l Earn: self. conn. rollback () raise ex_learn finally: self. conn. close () return learn_result def identify_data (self, test_data): ''' identifies and compares the data one by one, and returns the closest approximate value ''' try: table_data = [] for I in range (10): table_data.append (self. _ get_data (I, test_data) # return the index return table_data.index (min (table_data) of the minimum value in table_data except T Exception as ex_identify: raise ex_identify def _ get_data (self, table, test_data ):' '''Retrieve all the data in the table and compare it with the test data. Return the minimum value. if the table does not have any data, take 0''' try: if table <0 or table> 9: raise Exception ("error! The table value cannot be % d! "% Table) self. conn = pymssql. connect (host = '2017. 0.0.1 ', user = 'sa', password = '000000', database = 'pylearningdb', charset = 'utf8') self. cursor = self. conn. cursor () self. SQL = 'select * from table % d' % table self.cursor.exe cute (self. SQL) receive_ SQL = self. cursor. fetchall () if not receive_ SQL: new_receive_ SQL = [(0, 0, 0, 0, 0, 0, 0, 0)] else: new_receive_ SQL = receive_ SQL finally: self. conn. close () # Calculate the minimum dim_data = [] for receive_data in new_receive_ SQL: dim_data.append (self. _ distance_data (test_data, receive_data) # return the minimum value of return min (dim_data) def _ distance_data (self, test_data, table_data) in dimData ): ''' calculate the distance between two points in a nine-dimensional space ''' self. distance = 0.0 for I in range (9): self. distance + = (test_data [I]-table_data [I]) ** 2 return math. sqrt (self. distance)

3. Interaction with the interface through pyqt

The LearningUI. py program is as follows:

'''Learningui class functions: Generate UI interface, and define event handling methods Author: PyLearn blog: http://www.cnblogs.com/PyLearn/ Last modified Date: ''' from PyQt5.QtWidgets import (QWidget, QPushButton, QLabel, QComboBox, q1_topwidget) from PyQt5.QtGui import (QPainter, QPen, QFont) from PyQt5.QtCore import Qtclass LearningUI (QWidget): def _ init _ (self): super (LearningUI, self ). _ init _ () self. _ init_ui () # Set to keep track of movement only when the mouse is pressed; otherwise, draw self when the mouse is not pressed. setMo UseTracking (False) # self. pos_xy saves all painting points self. pos_xy = [] # Set pos_x and pos_y to conveniently calculate self. pos_x = [] self. pos_y = [] # Set the associated event self. btn_learn.clicked.connect (self. btn_learn_on_clicked) self. btn_recognize.clicked.connect (self. btn_recognize_on_clicked) self. btn_clear.clicked.connect (self. btn_clear_on_clicked) def _ init_ui (self): ''' defines the UI: three buttons: learning, recognition, clear screen btn_learn, btn_recognize, btn_clear a combo box: Select 0-9 combo_tab Two tags of le: enter a number in 0-9 in the blank area of the screen for identification! By PyLearn label_output ''' # add three buttons: learning, recognition, and clear screen self. btn_learn = QPushButton ("Learning", self) self. btn_learn.setGeometry (50,400, 70, 40) self. btn_recognize = QPushButton ("recognition", self) self. btn_recognize.setGeometry (320,400, 70, 40) self. btn_clear = QPushButton ("clear screen", self) self. btn_clear.setGeometry (420,400, 70, 40) # Add a combo box and select 0-9 self. combo_table = QComboBox (self) for I in range (10): self. combo_table.addItem ("% d" % I) self. combo_table.setGeometry (150,400, 70, 40) # Add two tags self. label_head = QLabel ('enter a number in 0-9 in the blank area of the screen for identification! ', Self) self. label_head.move (75, 50) self. label_end = QLabel ('2014/1/10 by pylearn', self) self. label_end.move (375,470) # Add a tag '''setstylesheet to set the border size, color setFont to set the font size, shape, and bold setAlignment to set the text center ''' self. label_output = QLabel ('', self) self. label_output.setGeometry (50,100,150,250) self. label_output.setStyleSheet ("QLabel {border: 1px solid black;}") self. label_output.setFont (QFont ("Roman t Imes ", 100, QFont. bold) self. label_output.setAlignment (Qt. alignCenter) ''' setFixedSize () fixed the width and height of the form self. center () center the form and display setWindowTitle (). Set the Form title '''self. setFixedSize (550,500) self. center () self. setWindowTitle ('0-9 handwriting recognition ("HelloWorld! ") ') Def center (self): ''' the center of the window shows ''' qt_center = self. frameGeometry () Export top_center = q1_topwidget (). availableGeometry (). center () qt_center.moveCenter (shorttop_center) self. move (qt_center.topLeft () def paintEvent (self, event ): ''' first judge whether there are at least two vertices in the pos_xy list, and then assign the first vertex in pos_xy to point_start. Use the intermediate variable pos_tmp to traverse the entire pos_xy list point_end = pos_tmp to determine whether point_end is a breakpoint, if point_start is assigned a value to the breakpoint continue to determine whether point_start is a breakpoint, if point_start is assigned a value to point_end continue to draw a line between point_start and point_end, point_start = point_end, and draw lines between adjacent two points continuously, you can move the cursor to the path ''' painter = QPainter () painter. begin (self) pen = QPen (Qt. black, 2, Qt. solidLine) painter. setPen (pen) if len (self. pos_xy)> 1: point_start = self. pos_xy [0] for pos_tmp in self. pos_xy: point_end = pos_tmp if point_end = (-1,-1): point_start = point_end continue if point_start = (-1,-1): point_start = point_end continue painter. drawLine (point_start [0], point_start [1], point_end [0], point_end [1]) point_start = point_end painter. end () def mouseReleaseEvent (self, event): ''' overwrite the mouse and hold it. Then, release the event. After each release, add a breakpoint (-1,-1) to the pos_xy list) then, when painting, you can determine whether it is a breakpoint. If it is a breakpoint, it will jump over, not with the previous continuous ''' pos_test = (-1,-1) self. pos_xy.append (pos_test) self. update () def mouseMoveEvent (self, event): ''' press and hold the mouse to move: add the Moving Point to self. pos_xy list ''' # self. pos_x and self. pos_y is always better than self. pos_xy has one or two points less, and you do not know the cause of self. pos_x.append (event. pos (). x () self. pos_y.append (event. pos (). y () # extract the current point pos_tmp = (event. pos (). x (), event. pos (). y () # Add pos_tmp to self. self in pos_xy. pos_xy.append (pos_tmp) self. update () def btn_learn_on_clicked (self): ''' databases are required. Therefore, the '''pass def btn_recognize_on_clicked (self): ''' must be used in the subclass, therefore, in the subclass, implement '''pass def btn_clear_on_clicked (self): '''. Press the clear screen button to leave the list blank, empty the tag of the output recognition result, and refresh the interface, you can clear the screen ''' self after painting again. pos_xy = [] self. pos_x = [] self. pos_y = [] self. label_output.setText ('') self. update () def get_pos_xy (self ): '''calculates the number of vertices in each cell by dividing the handwriting into nine grids on the plane, converts the number of vertices to the percentage of the total points, and returns an array dim [9] x-axis in sequence. the vertical axes of min_x, min2_x, max2_x, and max_x are min_y, min2_y, max2_y, and max_y ''' if not self. pos_xy: return None pos_count = len (self. pos_x) max_x = max (self. pos_x) max_y = max (self. pos_y) min_x = min (self. pos_x) min_y = min (self. pos_y) dim = [0, 0, 0, 0, 0, 0, 0, 0] dis_x = (max_x-min_x) // 3 dis_y = (max_y-min_y) // 3 min2_x = min_x + dis_x min2_y = min_y + dis_y max2_x = max_x-dis_x max2_y = max_y-dis_y for I in range (len (self. pos_x): if self. pos_y [I]> = min_y and self. pos_y [I] <min2_y: if self. pos_x [I]> = min_x and self. pos_x [I] <min2_x: dim [0] + = 1 continue if self. pos_x [I]> = min2_x and self. pos_x [I] <max2_x: dim [1] + = 1 continue if self. pos_x [I]> = max2_x and self. pos_x [I] <= max_x: dim [2] + = 1 continue elif self. pos_y [I]> = min2_y and self. pos_y [I] <max2_y: if self. pos_x [I]> = min_x and self. pos_x [I] <min2_x: dim [3] + = 1 continue if self. pos_x [I]> = min2_x and self. pos_x [I] <max2_x: dim [4] + = 1 continue if self. pos_x [I]> = max2_x and self. pos_x [I] <= max_x: dim [5] + = 1 continue elif self. pos_y [I]> = max2_y and self. pos_y [I] <= max_y: if self. pos_x [I]> = min_x and self. pos_x [I] <min2_x: dim [6] + = 1 continue if self. pos_x [I]> = min2_x and self. pos_x [I] <max2_x: dim [7] + = 1 continue if self. pos_x [I]> = max2_x and self. pos_x [I] <= max_x: dim [8] + = 1 continue else: pos_count-= 1 continue # convert the quantity to the percentage for num in dim: num = num* 100 // pos_count return dim

4. Interaction between the UI and the database

The Learning. py program is as follows:

'''Learning class function: override two methods in the LearningUI class that use the database: Add a data member of the LearningDB Class Object to the class self. learn_db Author: PyLearn blog: http://www.cnblogs.com/PyLearn/ Last modified Date: ''' from PyQt5.QtWidgets import QMessageBoxfrom LearningUI import LearningUIfrom LearningDB import LearningDBclass Learning (LearningUI ): '''learning implements the btn_learn_on_clicked and btn_recognize_on_clicked Methods ''' def _ init _ (self): super (Learning, self ). _ init _ _ () # Learn_data (table, dim) and identify_data (test_data) self. learn_db = LearningDB () def btn_learn_on_clicked (self): if not self. pos_xy: QMessageBox. critical (self, "NOTE", "write the number you want to learn first! ") Return None # obtain the number learn_num = self. combo_table.currentIndex () # The pop-up confirmation dialog box qbox = QMessageBox () qbox. setIcon (QMessageBox. information) qbox. setWindowTitle ("Please confirm") qbox. setText ("learning numbers % d? "% Learn_num) qbox. setStandardButtons (QMessageBox. yes | QMessageBox. no) qbox. setDefaultButton (QMessageBox. no) qbox. button (QMessageBox. yes ). setText ("yes") qbox. button (QMessageBox. no ). setText ("no") reply = qbox.exe c () # determine the result of the dialog box and run the program if reply = QMessageBox. yes: learn_result = False learn_dim = self. get_pos_xy () if learn_dim: learn_result = self. learn_db.learn_data (learn_num, learn_dim) else: print ('get _ Pos_xy () function returns NULL value ') return None if learn_result: QMessageBox. about (self, "prompt", "learning successful! ") Else: QMessageBox. about (self," prompt "," Learning failed! ") Else: return None def btn_recognize_on_clicked (self): # if no painting is performed, exit if not self after warning. pos_xy: QMessageBox. critical (self, "NOTE", "write the number you want to recognize first! ") Return None else: recognize_num = 0 recognize_dim = self. get_pos_xy () if recognize_dim: recognize_num = self. learn_db.identify_data (recognize_dim) else: print ('recognize _ dim blank ') return None self. label_output.setText ('% d' % recognize_num)

5. The final main Function

'''Main function main function: generate a Learning object and enter the main cycle Author: PyLearn last modification date: ''' import sysfrom PyQt5.QtWidgets import QApplicationfrom Learning import Learningif _ name _ = '_ main _': app = QApplication (sys. argv) py_learning = Learning () py_learning.show () sys.exit(app.exe c _())

Put the above four programs in the same directory and directly execute main. py.

The running interface is as follows:

Learning number 4:

The first operation requires at least one learning to have a correct rate.

Identification 3:

The above Python3 implements simple and learnable handwriting recognition (for example), which is all the content shared by the editor. I hope it can be used as a reference and a great support for helping customers.

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.