宋汝良,施運淵
(上海夢創雙楊數據科技股份有限公司,上海 200333)
隨著人們越來越追求生活的便利,普通計算器已無法滿足人們的需求。手寫計算器允許用戶像在紙上一樣在自己的移動電話或平板電腦上寫不同的公式,并獲得計算結果。由于手寫計算器學習成本低,操作簡單,它為人們的學習、工作和生活帶來了極大的便利。
可手寫算式計算器首先要求能對手寫的文字、數字及符號進行識別。光學字符識別技術為這一需求提供了條件。光學字符識別(Optical Character Recognition,OCR)是指通過電子設備(例如掃描儀或數碼相機)檢查打印在紙上的字符,通過檢測深色和明亮圖案確定形狀,然后將形狀轉換為使用字符識別方法的計算機文本[1]。手寫字符識別一直是模式識別領域研究的前沿領域,在圖像處理中對手寫文檔的OCR有很大的需求。研究人員已經提出了許多用于字符識別的方法,歷史上字符識別系統已經發展了大致3個時代[8]。最早的字符識別器出現在20世紀40年代中期,直到1980年的研究都受到強大的計算機硬件和數據采集的推動。然而,字符識別研究主要集中在不使用任何語義信息的形狀識別技術上。1990年后,字符識別系統的真正進步是在不斷增長的信息技術的支持下使用新的方法和開發工具實現的。20世紀90年代初期,圖像處理和模式識別技術與人工智能方法有效結合。如今,除了功能更強大的計算機和諸如照相機、掃描儀和電子平板電腦之類的精確電子設備外,研究人員還有效利用了諸如隱馬爾可夫模型、神經網絡等方法。市面上也出現了各種開源OCR庫,其中的Tesseract非常強大,它可以支持包括中文在內的60多種語言的識別,并且可以由用戶自定義字體。我們將手寫字體作為一種自定義字體,便可以利用Tesseract庫對手寫文本進行識別。
在對圖像中的文本進行識別前,使用閾值分割[2]等方法對圖像進行處理時常用的手段。閾值化是最簡單的圖像分割方法,閾值可用于從灰度圖像中創建二進制圖像。二值圖像還可通過分割方法由彩色圖像生成。分割是將源圖像中的每個像素分配給兩個或更多類的過程。閾值分割技術中,常用的閾值選取方法包括灰度直方圖峰谷法[3]、最小誤差法[4]、Otsu法[5]、最大熵自動閾值法[6-7]等。其中Otsu法被認為是閾值選取的最優方法之一。
網絡時代的來臨為人們的生活帶來了極大便利,手機等移動端產品越來越普及。微信作為智能終端下跨平臺的即時通信工具,具有十分龐大的用戶群體[9]。為了進一步方便用戶體驗手寫計算器的便利,我們以微信小程序的形式呈現最終的程序。微信小程序是一種無須下載即可使用的應用程序,它基于微信這一廣泛使用的應用程序,以類似于網頁應用的形式呈現給用戶。用戶可以通過掃描二維碼或在微信中進行搜索來打開應用程序。
本項目是一個微信小程序,可用于識別和計算手寫數學公式。進入小程序后,有兩個界面:識別界面和個人信息界面。在識別界面中,用戶可以選擇直接手寫數學公式進行計算,也可以上傳照片進行識別。編寫公式時,如果輸入有誤,則可以使用“橡皮擦”功能擦除書寫的部分或選擇清空畫布。上載照片將要求用戶使用相機授予小程序并獲得相冊。用戶選擇照片后,單擊“上載”按鈕將照片上載到服務器。我們將使用Python腳本和Tesseract來處理,識別和計算用戶上傳的圖像。識別結果和計算結果將返回給用戶。用戶可以選擇收集此計算。在個人信息界面中,用戶可以查看個人收藏夾和歷史記錄并管理收藏夾。項目具有如下具體功能:
(1)識別手寫算式。微信小程序提供了一個畫布控件,可用于獲取用戶手指在控件范圍內的移動。我們為畫布設置淺色背景,并用黑色標記書寫軌跡,可以有效增強前景背景的對比度,從而提高識別精度。
(2)識別圖片中的算式。對于用戶上傳的圖像,我們使用閾值分割等方法對圖像進行處理,并將其轉換為清晰的二進制圖像以進行識別。
(3)計算結果。識別結果將首先轉換為特定的格式字符串,以表示數學公式及其空間結構。然后使用python腳本來處理和計算字符串以獲得最終結果。
(4)收藏與歷史。用戶可以選擇在返回結果后收藏或取消收藏,或者在個人信息界面中查看歷史記錄和管理收藏。
微信小程序基于MCCM框架的思想,網頁與數據緊密結合。數據上的每次更改都會更改或重新呈現網頁。在微信小程序中,這種操作是通過功能“setData”來實現的,在該功能中傳遞了重新渲染功能。

圖1 可手寫算式計算器微信小程序首頁
本文所提出的可手寫算式計算器的微信小程序首頁設計如圖1所示。首頁分為3個主要模塊,分別為圖片識別(淺色區域)、手寫識別(深色區域)和下方的任務欄。用戶可以選擇使用圖片識別功能,來識別圖片中的算式并獲取計算結果。當選擇手寫識別功能時,用戶可以在屏幕上手寫算式并識別、計算。圖片識別和手寫識別模塊如圖2所示。

圖2 圖片識別(左)和手寫識別(右)
我們也提供了收藏和查看計算歷史的功能,幫助用戶快速找到之前計算過的結果。收藏和歷史功能的界面如圖3所示。

圖3 收藏功能(左)和歷史功能(右)
本項目后端使用Django框架。我們共設計了兩個Django模型,分別為WeUser模型和RecognizeItem。WeUser用來保存用戶信息以及和數據庫交互。RecognizeItem模型用來保存每次的識別記錄。本項目共包含9個視圖,分別對應圖片上傳、識別、計算、收藏、取消收藏,以及識別記錄、用戶信息、識別歷史、收藏的查詢等。
3.3.1 Tesseract模型訓練
我們選擇數學字符集來訓練模型,并生成了訓練數據的標準模式。一個標準的訓練數據集合示例如圖4所示。

圖4 Tesseract模型訓練數據示例
我們將數學符號作為一種新的字體。這種新的字體被用于訓練并被保存,之后我們使用了輔助工具(jTessBoxEditor.jar等)對訓練結果進行更正,以獲得更精準的結果。
3.3.2 識別
所有被捕獲或者上傳的圖片將首先經過Python腳本的二值化處理,以獲取更清晰的算式圖像[10]。之后對于二值圖像,程序將根據其空間結構對其進行分塊,并分別對每一塊進行識別。通過分塊,程序將可以有效識別分數、根式、指數、對數、三角函數等復雜算式。分塊的主要思想是在像素基本檢測包含手寫文本的區域是否存在空白行或者空白列,這些空白的行和列將作為分塊的分割線。根據分塊所在空間位置,程序將對結果進行組合,并得到最終結果。
本項目是一個可識別并計算手寫算式的微信小程序,使用Django作為服務后端,使用Python結合開源項目Tesseract的方式進行手寫算式的識別。具有輕量級、界面清爽、功能全面、使用簡單的優點。本項目也在持續更新中,后續本項目將支持更多算式的計算,并努力提升識別的精確度,為用戶帶來更好的體驗。