Tess4.0手動合并輸入數(shù)據(jù)及模型訓(xùn)練流程

之前,寫過一篇文章特殊字符語言包訓(xùn)練流程(新)記錄了Tess4.0訓(xùn)練模型的流程量承。但是由于Tesseract的系統(tǒng)限制蹭越,Tess4.0無法自動訓(xùn)練中文正體和英文斜體的混合文本,因此棋电,后來寫了文章Tess4.0中英文正體斜體混合訓(xùn)練記錄了中文正體和英文斜體的訓(xùn)練流程振劳。然而椎组,這篇文章里暴力地將所有中文正體放在一個(gè)頁面,英文斜體放在另一個(gè)頁面历恐。因此庐杨,Tess4.0無法學(xué)習(xí)到中英文文本之間的順序。為了解決中文正體和英文斜體之間的順序識別問題夹供,這篇文章記錄了手動合并Tess4.0的輸入數(shù)據(jù)的過程灵份。手動合并的數(shù)據(jù)很好地融合了中文正體和英文斜體之間的順序信息。這樣哮洽,Tess4.0后期的LSTM網(wǎng)絡(luò)結(jié)構(gòu)可以很好地學(xué)習(xí)到中文正體和英文斜體之間的順序信息填渠。

Tess輸入數(shù)據(jù)生成步驟

初步分析,Tess4.0的輸入數(shù)據(jù)主要由tif和box兩個(gè)文件組成,其中tif2文件是Tess待識別的圖片氛什,box文件中記錄了每個(gè)字符在圖片中的位置信息≥汉現(xiàn)在我們假設(shè)所有的文本信息記錄在txt文本中,下面闡述生成tif和box文本的流程枪眉。

txt文本信息轉(zhuǎn)存到word文檔

由于需要學(xué)習(xí)txt文本中的英文斜體信息(txt不支持正體和斜體同步出現(xiàn)的情況)捺檬,我們需要將txt中的所有文本按順序轉(zhuǎn)存到word中,其中贸铜,中文設(shè)置為宋體正體堡纬,英文設(shè)置為Times new Roman斜體。其主要python代碼如下:

document = Document()
for eachLine in content_lines.split('\n'):  //content_lines讀取的txt文本中的內(nèi)容
    p = document.add_paragraph()            //所有數(shù)據(jù)保存在document對象中蒿秦,讀入數(shù)據(jù)以后保存到相應(yīng)路徑下
    if eachLine == '':
        continue
    for each_word in eachLine:
        if is_alphabet(each_word): //字母以Times New Roman斜體形式保存
            run = p.add_run(each_word + '       ')
            run.font.name = u'Times New Roman'
            run.italic = True
        else:
            run = p.add_run(each_word + '    ')  //其他字符保存宋體正體
            if each_word == '_':
                run.font.bold = True
                run.italic = True
            run.font.name = u'宋體'
            run._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋體')
document.save('word_path')

word文檔轉(zhuǎn)圖片

已經(jīng)得到了中文正體和英文斜體混合的word文檔烤镐,下面就是將其轉(zhuǎn)化為圖片信息。轉(zhuǎn)為圖片的目的是截取每個(gè)字符的box位置棍鳖,由于字符之間的間距很小炮叶,截取box位置難度較大。為了提高字符的截取精度渡处,在上一步驟轉(zhuǎn)存word文檔時(shí)镜悉,我們故意在每個(gè)字符后面添加一些空格,這樣字符之間的間距增大医瘫,就降低了字符截取的難度积瞒。

在word轉(zhuǎn)圖片時(shí),首先將word轉(zhuǎn)存為pdf文檔登下,然后利用下面的java代碼轉(zhuǎn)為tif圖片:

public static void main (String[] args) {
        // TODO Auto-generated method stub
        String filePath = "math_data.pdf";
        File file = new File(filePath);
        try {
            PDDocument doc = PDDocument.load(file);
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            for(int i=0;i<pageCount;i++){
                BufferedImage image = renderer.renderImageWithDPI(i, 296);
                String saveFilePath = "./test_data/";
                saveFilePath += "image";
                saveFilePath += "_";
                saveFilePath += filePath;
                saveFilePath += "_";
                saveFilePath += i;
                saveFilePath += ".tif";
                System.out.println("saveFilePath = " + saveFilePath);
                ImageIO.write(image, "tif", new File(saveFilePath));
            }
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

這些代碼基本修改于網(wǎng)絡(luò)上現(xiàn)成的程序,所以不同的數(shù)據(jù)處理步驟用了不同的語言(python, java, 后面的代碼還有用到C++的)叮喳。

box文件提取與圖像字符重組

在提取字符box位置時(shí)被芳,主要思路是二值化,水平投影截取行馍悟,再垂直投影截取字符位置畔濒。然后將截取出來的字符重新排列位置,主要調(diào)整字符之間的距離锣咒,順序不變侵状,并調(diào)整相應(yīng)的box位置 。代碼流程框架見下:

CutWords cutWords = CutWords();
Mat srcImage = imread(path);  // 獲取原圖
Mat srcImageBin;
srcImageBin = cutWords.horizonProjection(srcImage);  // 二值化并且水平投影
cutWords.combineBlob();  // 融合行處理
list<Mat> lineImgs = cutWords.cutLine(srcImageBin);  // 截取行
//cutWords.regionLines(srcImage);  // 畫出行截取的中間結(jié)果
cutWords.verticalProjection(lineImgs);  // 對每行進(jìn)行垂直投影毅整,截取字符
cutWords.combineBox();  // 融合字符處理
//cutWords.regionWords(srcImage); // 畫出字符截取結(jié)果
//waitKey(0);
srcImageBin = cutWords.adjustBoxLocation(srcImageBin, pageNum);  // 調(diào)整字符位置和box文件
sprintf(saveBox, "E:/javaWorkspace/PdfConvertImage/test_box/boxdata_%d.txt", pageNum);
cutWords.writeBoxFile("E:/jiequ.txt", saveBox, pageNum, srcImageBin);  // 畫出box文件和新的圖片

由代碼注釋可見主要的處理過程趣兄。

box文件后續(xù)處理

上一步驟的box文件生成的結(jié)果與Tesseract的輸入文件存在一定的偏差,需要將具體的文本字符和box文件進(jìn)行合并悼嫉,并且添加圖片中的行轉(zhuǎn)換提示符艇潭。因此需要對box文件后續(xù)處理。

處理步驟如下:

  1. 將字符與box文件進(jìn)行合并,上一步驟中只有box位置信息蹋凝,但每個(gè)位置對應(yīng)的字符并沒有給出鲁纠,這里需要將字符信息與位置信息對應(yīng);
  2. 每個(gè)字符之間需要插入一些轉(zhuǎn)行提示符鳍寂。

具體的處理代碼如下:

tag = 0
for file_path in html_dir:
    tag += 1
    fopen = open('E:/數(shù)據(jù)/math_html/' + file_path, 'rb')
    content_lines = fopen.read().decode('utf-8')
    for eachLine in content_lines.split('\n'):
        each_box_line = ''
        if box_num < len(box_text)-1:
            for each_word in eachLine: # 每行數(shù)據(jù)進(jìn)行處理
                print(box_text[box_num])
                if each_word == ' ' or each_word == ' ' or each_word == ' ' or \
                                each_word == ' ' or each_word == '?' or each_word == '': # 排除文本中的特殊字符
                    continue
                if box_num +1 == len(box_text)-1:
                    box_num += 1
                    break
                box_line += each_word + ' ' + box_text[box_num] + '\r\n'  # 合并字符和位置信息
                if len(box_text[box_num+1].split(' ')) > 2:  # 插入轉(zhuǎn)行符
                    if box_text[box_num].split(' ')[1] != box_text[box_num+1].split(' ')[1]:
                        box_line += '   ' + ' ' + str(int(box_text[box_num].split(' ')[0])+60) + ' ' + \
                                    box_text[box_num].split(' ')[1] + ' ' + str(int(box_text[box_num].split(' ')[2])+60) \
                                    + ' ' + box_text[box_num].split(' ')[3] + ' ' + box_text[box_num].split(' ')[4] + '\r\n'
                box_num += 1
            if len(box_text[box_num+1].split(' ')) > 2:
                if box_text[box_num].split(' ')[1] != box_text[box_num+1].split(' ')[1]:
                    box_line += '   ' + ' ' + str(int(box_text[box_num].split(' ')[0])+60) + ' ' + \
                                box_text[box_num].split(' ')[1] + ' ' + str(int(box_text[box_num].split(' ')[2])+60) \
                                + ' ' + box_text[box_num].split(' ')[3] + ' ' + box_text[box_num].split(' ')[4]+ '\r\n'
            box_num += 1

驗(yàn)證box和tif的生成結(jié)果

tif和box文件都是由我們自己根據(jù)txt文檔生成的改含,生成的結(jié)果如何驗(yàn)證很重要。這里我們給出驗(yàn)證數(shù)據(jù)質(zhì)量的方法:

  1. 下載安裝jTessBoxEditor工具迄汛,具體的工具使用方法可以查看日志:android中tesseract-ocr自定義字庫的介紹捍壤。這里不再贅述;
  2. 提取box文檔中的其中一頁的box信息隔心,提取方法如下:
    updated_box_file = open('E:/javaWorkspace/PdfConvertImage/math_data.box', 'rb')
    text_content = updated_box_file.read().decode('utf-8').strip()
    
    box_page = 15
    reault = ''
    for each_box in text_content.split('\r\n'):
        try:
            if int(each_box.split(' ')[5]) == box_page:
                reault += each_box.split(' ')[0] + ' ' + each_box.split(' ')[1] + ' ' + each_box.split(' ')[2] + ' ' \
                          + each_box.split(' ')[3] + ' ' + each_box.split(' ')[4] + ' 0' + '\r\n'
        except:
            print(each_box)
    open('E:/javaWorkspace/PdfConvertImage/test_data/image_math_data.pdf_'+str(box_page)+'.box', 'wb').write(reault.encode('utf-8'))
    
  3. 將對應(yīng)的tif文件和box文件相同命名白群,并且放入同一目錄下,用jTessBoxEditor加載圖片硬霍,驗(yàn)證box信息是否正確帜慢。

合并tif和box文件

由于訓(xùn)練數(shù)據(jù)量要求比較大,這里我們生成了很多tif圖片需要進(jìn)一步合并唯卖,box文件也需要相應(yīng)的處理粱玲。具體的處理方法可見Tess4.0中英文正體斜體混合訓(xùn)練文章中的合并中英文數(shù)據(jù)章節(jié)。這里直接給出合并box文件的代碼:

box_file1 = open('E:/jTessBoxEditorFX/tesseract-ocr/temp_roman/chi_sim.SIMSUN_roman.exp0.box', 'rb').read().decode('utf-8')
box_file2 = open('E:/jTessBoxEditorFX/tesseract-ocr/temp_roman/math_data.box', 'rb').read().decode('utf-8')

box_content = box_file1 + '\n' // 第一個(gè)文件中的內(nèi)容直接拷貝到box_content變量中
box1_page_num = 0
for line in box_file1.split('\n'): // 獲取第一個(gè)文件中的頁碼數(shù)
    if len(line) > 0:
        page_num = int(line.split(' ')[len(line.split(' '))-1])
    if page_num > box1_page_num:
        box1_page_num = page_num

box1_page_num += 1
for line in box_file2.split('\r\n'): // 合并第二個(gè)文件
    if len(line) > 0:
        page_num1 = int(line.split(' ')[len(line.split(' '))-1])
        sub_line = ''
        for i in range(len(line.split(' '))-1):
            sub_line += line.split(' ')[i] + ' '
        box_content += sub_line + str(page_num1+box1_page_num) + '\n'

open('E:/jTessBoxEditorFX/tesseract-ocr/temp_roman/chi_sim.SIMSUN_roman.exp1.box', 'bw').write(box_content.encode('utf-8'))

print('merge success!')

訓(xùn)練Tesseract模型

在閱讀本章節(jié)之前建議詳細(xì)閱讀Tess4.0中英文正體斜體混合訓(xùn)練這篇文章拜轨,這里的處理步驟原理與Tess4.0中英文正體斜體混合訓(xùn)練文章中的神經(jīng)網(wǎng)絡(luò)輸入數(shù)據(jù)準(zhǔn)備章節(jié)的處理步驟一致抽减。更詳細(xì)的訓(xùn)練模型的方法步驟可以參考文章特殊字符語言包訓(xùn)練流程(新)或者github中給出的詳細(xì)教程

tif和box文檔生成的具體步驟

  1. 將所有待識別的數(shù)據(jù)以txt文檔的格式放入./data/alltxt_input文件夾中橄碾;
  2. 運(yùn)行./txt2word.py腳本卵沉,生成word_data.docx在./data/目錄下;
  3. 將./word_data.docx文件手動打開法牲,并存儲為PDF格式保存在相同目錄下史汗;
  4. 運(yùn)行./PdfConvertImage/src/testConvert.java文件,將pdf文檔轉(zhuǎn)存為tif文件拒垃,并存儲在./data/img_tif/目錄下停撞;
  5. 運(yùn)行./OCR_Process/OCRMain.cpp文件,截取box并調(diào)整字符圖片位置悼瓮,box文件存儲在./data/txt_box/目錄下戈毒,tif存儲在./data/adjust_img_tif/目錄下;
  6. 運(yùn)行./boxfile_update.py腳本横堡,合并字符與box信息埋市。

這樣,Tesseract的輸入數(shù)據(jù)就已經(jīng)生產(chǎn)好了命贴。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恐疲,一起剝皮案震驚了整個(gè)濱河市腊满,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌培己,老刑警劉巖碳蛋,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異省咨,居然都是意外死亡肃弟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進(jìn)店門零蓉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笤受,“玉大人,你說我怎么就攤上這事敌蜂÷崾蓿” “怎么了?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵章喉,是天一觀的道長汗贫。 經(jīng)常有香客問我,道長秸脱,這世上最難降的妖魔是什么落包? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮摊唇,結(jié)果婚禮上咐蝇,老公的妹妹穿的比我還像新娘。我一直安慰自己巷查,他們只是感情好有序,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著岛请,像睡著了一般旭寿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上髓需,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天,我揣著相機(jī)與錄音房蝉,去河邊找鬼僚匆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛搭幻,可吹牛的內(nèi)容都是我干的咧擂。 我是一名探鬼主播,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼檀蹋,長吁一口氣:“原來是場噩夢啊……” “哼松申!你這毒婦竟也來了云芦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤贸桶,失蹤者是張志新(化名)和其女友劉穎舅逸,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體皇筛,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡琉历,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了水醋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旗笔。...
    茶點(diǎn)故事閱讀 40,861評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖拄踪,靈堂內(nèi)的尸體忽然破棺而出蝇恶,到底是詐尸還是另有隱情,我是刑警寧澤惶桐,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布撮弧,位于F島的核電站,受9級特大地震影響耀盗,放射性物質(zhì)發(fā)生泄漏想虎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一叛拷、第九天 我趴在偏房一處隱蔽的房頂上張望舌厨。 院中可真熱鬧,春花似錦忿薇、人聲如沸裙椭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽揉燃。三九已至,卻和暖如春筋栋,著一層夾襖步出監(jiān)牢的瞬間炊汤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工弊攘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抢腐,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓襟交,卻偏偏與公主長得像迈倍,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子捣域,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評論 2 361

推薦閱讀更多精彩內(nèi)容

  • Tesseract中英文正體斜體混合訓(xùn)練 當(dāng)我們識別數(shù)據(jù)中包含中文正體啼染,英文斜體字符時(shí)宴合,Tess4.0識別英文斜體...
    RobertY閱讀 4,819評論 1 8
  • 個(gè)人學(xué)習(xí)批處理的初衷來源于實(shí)際工作;在某個(gè)迭代版本有個(gè)BS(安卓手游模擬器)大需求迹鹅,從而在測試過程中就重復(fù)涉及到...
    Luckykailiu閱讀 4,733評論 0 11
  • 《ilua》速成開發(fā)手冊3.0 官方用戶交流:iApp開發(fā)交流(1) 239547050iApp開發(fā)交流(2) 1...
    葉染柒丶閱讀 10,808評論 0 11
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理卦洽,服務(wù)發(fā)現(xiàn),斷路器徒欣,智...
    卡卡羅2017閱讀 134,715評論 18 139
  • 今天是四點(diǎn)二十起床逐样。 從開春到現(xiàn)在,從第二次說100天早睡早起打肝,又在艱難的堅(jiān)持中最后不得不放棄脂新。從堅(jiān)持到勉強(qiáng)在堅(jiān)持...
    朱泓默閱讀 313評論 5 6