基於Tesseract-OCR的空調外包裝表面的字符識別

是我們圖像處理課程的期末考試題,將報告總結一下,寫成博客。
1.python、IDE、opencv的安裝
2.PIL、pytesseract、ocr引擎的安裝與中文庫的使用
3.tesseract的字庫訓練

目的:在空調生產出廠時,需要將不同型號的空調機裝入與表面印有空調機的型號一致的包裝盒。爲避免空調機型號和外包裝型號不一致,需要對外包裝表面字符進行檢測與識別。方法:首先對外包裝圖像進行預處理,利用自適應閾值法對圖像二值化,使用形態學操作對圖像濾噪點,輪廓提取濾噪點。然後使用Tesseract對外包裝進行識別,對字庫進行訓練,建立OCR引擎,最後驗證。結果:經過驗證,本文識別準確率爲97.77%。結論:基於Tesseract建立的空調外包裝OCR引擎可以實現生產智能化,極大提高效率,有助於數據的進一步利用。

0 引言

在空調生產出廠時,需要將不同型號的空調機裝入與表面印有空調機的型號一致的包裝盒。爲避免空調機型號和外包裝型號不一致,需要對外包裝表面字符進行檢測與識別,爲了提高工作效率,實現生產智能化。本文將使用Tesseract進行鍼對性的訓練,設計並實現空調外包裝的識別,基於Tesseract建立OCR引擎。

1 方法

1.1外包裝表面圖像的預處理

由於圖像在拍攝時受到外界環境的影響,如光照過強、光照不足或光照不均勻,空調外包裝的移動,相機本身硬件的影響,拍攝的圖片,可能圖片存在模糊、不清晰、光照不均勻等情況。因此,爲了保證字符識別的效果,提高字符識別的準確,在識別字符之前,圖像進行預處理可以儘量減少圖像背景對文字區域的干擾,爲之後進行字符識別做好一個很好的鋪墊[1]。在對空調外包裝圖像進行預處理包括:讀取圖像、灰度化、二值化、形態學操作、輪廓提取、濾除噪點,本問的總體預處理過程如圖1所示。
在這裏插入圖片描述

1.1.1 外包裝圖像灰度化和二值化

通過相機獲取到的圖像是彩色圖像,將彩色圖像轉化爲灰度圖像的過程爲圖像灰度化處理。灰度化的方式有分量法、最大值法、平均值法、加權平均法。本文使用是OPENCV計算機計算機和視覺庫中的彩色圖像轉灰色圖像,具體用到的線性灰度變換函數是:
Gray=0.299R+0.587G+0.144*B

圖像的二值化在視覺檢測領域是很關鍵的一步,常用的二值化方法有固定閾值二值化、直方圖閾值法、大津法、自適應閾值法等。空調外包裝圖像經常出現光照強度不同,不均勻等等情況。在使用大津法後,發現文字區域出現大量黑色區域,如圖2。自適應閾值法能將文字能很好的保留下來,同時背景只留下了噪點,效果是最佳的,如圖2。
自適應閾值法:它的思想不是計算全局圖像的閾值,而是根據圖像不同區域亮度的分佈,計算其局部閾值,所以對於不同圖形不同區域,能夠自適應計算不同的閾值。這種局部閾值法正好解決了空調外包裝圖像光照不均勻影響,能很好的保留圖片的信息,降低了陰影對圖像的影響。
在這裏插入圖片描述

1.1.2 外包裝圖像形態學操作

圖像經過自適應二值化後,背景還留下了很多小噪點,我們可以用圖像中的形態學開操作濾除一部分噪聲。

開操作:先腐蝕後膨脹,它的特點是使圖像的輪廓變得光滑,使狹窄的連接斷開和消除毛刺、濾除噪點,同時沒有明顯影響圖像的面積、形狀,如圖3。
在這裏插入圖片描述

1.1.3 圖像輪廓提取和濾除噪點

圖像經過形態學操作後,在不影響文字的形狀的情況下,發現還有些許噪點無法濾掉,我們通過面積閾值法,將這些背景的噪點濾掉。
使用opencv中的findContours函數找到圖像中的所有輪廓信息並進行了標記,如圖4

在這裏插入圖片描述
根據輪廓的提取算的得每個輪廓的面積,再給定一個面積的閾值,將這些噪點全部變爲背景,不影響字符的識別,如圖5。
在這裏插入圖片描述

1.2 Tesseract-OCR的字符訓練

Tesseract是一個開源的OCR(Optical Character Recognition,光學字符識別)引擎,可以識別多種格式的圖像文件並將其轉換成文本,目前已支持60多種語言(包括中文)。

Tesseract最初由HP公司開發,後來由Google維護。它的精確度在1995年的測試中名列前三,其最近的目標是在準確度上再次趕超商業OCR引擎[2]。用戶可以用自己的樣本來訓練新的字庫,本文用Tesseract爲基礎,完成了空調外包裝的字符識別。

Tesseract在識別過程中採用了集束搜索算法與K近鄰算法。集束搜索是一種啓發式圖搜索算法, 具有較好的時間和空間複雜度。Tesseract運用集束 搜索算法對字符進行分割。K近鄰算法法是計算一個點與樣本空間所有點之間的距離,取出與該點最近的k個點,統計得出這k個點裏面所屬分類比例最大的點。Tesseract使用K近鄰算法來返回最匹配的識別樣本[3]。
圖5展示了基於Tesseract的空調外包裝字符的OCR訓練步驟。
在這裏插入圖片描述

1.2.1 字庫訓練步驟

(1)製作Tiff訓練樣本。準備一定量的樣本,本文準備了6張圖片做樣本,將其轉爲.tiff格式,使用jTessBoxEditor生成.font.exp0.tif文件

(2)生成BOX文件。使用tesseract在命令行中執行tesseract char.font.exp0.tif char.font.exp0 batch.nochop makebox,生成char.font.exp0.box。

(3)使用jTessBoxEditor進行字符矯正。修改左側文字識別錯誤的過程,並且可以通過Merge、Split、Insert、Delete來合併、分離、添加、刪除識別框,如圖6所示。
在這裏插入圖片描述
(4)使用tesseract生成.tr訓練文件。使用tesseract在命令行中執行tesseract char.font.exp0.tif char.font.exp0 nobatch box.train,生成char.font.exp0.tr文件。

(5)計算字符集,生成Unicharset文件。Unicharset文件包含了Tesseract引擎訓練後可以識 別的每個字符的信息,它是Tesseract新字庫語言的一部分。在命令行中執行unicharset_extractor char.font.exp0.box,生成unicharset文件。

(6)生成shape文件。執行命令:shapeclustering -F font_properties -U unicharset -O char.unicharset char.font.exp0.tr生成shapetable 和 char.unicharset 兩個文件

(7)生成聚字符特徵文件。執行命令:
mftraining -F font_properties -U unicharset -O char.unicharset char.font.exp0.tr。生成inttemp、pffmtable、shapetable和char.unicharset四個文件。

(8)生成字符正常化特徵文件。執行命令:
cntraining char.font.exp0.tr
(9)合併訓練文件生成的.traineddata。通過命令combine_tessdata char合併所有文件生成字典文件。

1.3 空調外包裝圖像的字符識別

1.3.1 使用的平臺

(1)python3.6。Python是一種跨平臺的計算機程序設計語言。是一種面向對象的動態類型語言,最初被設計用於編寫自動化腳本(shell),隨着版本的不斷更新和語言新功能的添加,越來越多被用於獨立的、大型項目的開發。

(2)python-opencv。OpenCV是一個基於BSD許可(開源)發行的跨平臺計算機視覺庫,可以運行在Linux、Windows、Android和Mac OS操作系統上。它輕量級而且高效——由一系列 C 函數和少量 C++ 類構成,同時提供了Python、Ruby、MATLAB等語言的接口,實現了圖像處理和計算機視覺方面的很多通用算法。

(3)Pytesseract模塊。是使用python語言封裝,以光學字符識別引擎Tesseract-OCR爲底層接口模塊。Pytesseract模塊應用十分靈活,支持PIL讀取各種傳統的圖像文件,同時Pytesseract還支持OPENCV圖像或者Numpy數組對象,使得圖像處理和識別的過程更加靈活。

1.3.2 圖像字符識別

(1)採用Tesseract-OCR官方給的中文庫,直接進行識別的效果並不好,很多字符誤識別、、多識別、漏識別的情況比較嚴重,測試結果如圖7。
在這裏插入圖片描述
(2)首先在python環境下使用opencv將圖像預處理後,得到一張圖像字符明顯,背景乾淨的圖片。再通過Pytesseract調用訓練好的字典文件進行字符的識別。訓練結果,如圖8所示。
在這裏插入圖片描述

2 識別準確率的驗證結果以及分析

爲驗證該方法的有效性和準確率,本文使用了45張字符角度不同,光照不均勻等圖片進行識別測試。實驗結果顯示44張圖能識別完全正確,另有1張圖片識別結果有誤。準確率爲97.77%

識別結果有誤的圖像的測試結果如圖9所示。將在‘內’與‘機’之間多識別了一個‘室’。出現這種情況的原因(1)相機未將字符拍攝完整。(2)Tesseract軟件本身對字體的判斷有不準確性。(3)本文所採用的訓練樣本不足,導致的識別判斷率低。
在這裏插入圖片描述

結 語

本文通過讀取圖像,經過灰度化、二值化、形態學操作、去噪點後使用Tesseract將空調外包裝的字符較乾淨的提取出來。

從識別效果,最後的準確率來看,本引擎經過詞典以及模糊字 校正之後,總體識別率爲97.77%。識別率相對較高,但是仍然有誤識別的情況,在不改變其他情況,通過增加樣本的訓練,識別率會逐漸增加。

代碼

import cv2 as cv
import numpy as np
from PIL import Image
import pytesseract as tess

# 傳入二值化的圖像
def contour_demo(image):
    image = cv.bitwise_not(image)
    contour_image = cv.cvtColor(image, cv.COLOR_BGR2RGB)

    contours, heriachy = cv.findContours(image, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    for i, contour in enumerate(contours):
        # cv.drawContours(contour_image, contours, i, (0, 0, 255), 2)  # 2->-1 填充
        x, y, w, h, = cv.boundingRect(contour)
        area = cv.contourArea(contour)
        rect = cv.boundingRect(contour)
        cv.rectangle(contour_image, (x, y), (x+w, y+h), (0, 0, 255), 2)
        print(area)
        print(rect)
        if area < 35:
            # roi = contour_image[y:y+h, x:x+w]
            roi = 0
            # contour_image[y:y+h, x:x+w] = roi
            image[y:y+h, x:x+w] = roi
        print(i)

    cv.imshow("contour_image", contour_image)
    image = cv.bitwise_not(image)
    cv.imshow("image", image
    textImage = Image.fromarray(image)
    # 識別
    txt = tess.image_to_string(textImage, lang='char')
    print("識別結果爲:\n", txt)

def image_handle():
    gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
    cv.imshow("grayscale", gray)

    ret, bin = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    cv.imshow("OTSU", bin)

    adapt_bin = cv.adaptiveThreshold(gray, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 255, 30)
    cv.imshow("adaptive threshold", adapt_bin)

    kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (2, 2))
    dilate_image = cv.dilate(adapt_bin, kernel)
    cv.imshow("dilate_image", dilate_image)

    kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (2, 2))
    erode_image = cv.erode(dilate_image, kernel)
    cv.imshow("erode_image", erode_image)

    contour_demo(erode_image)


print("外包裝表面字符:")
src_image = cv.imread("G:\\Python\\lesson_test\\6.jpg")  # 6 15  20 22
cv.imshow("src", src_image)

src = src_image[100:800, 0:1280]
image_handle()

cv.waitKey(0)
cv.destroyAllWindows()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章