Halcon OCR--字符識別(CNN卷積神經網絡)

2021-03-02 勇哥的機器視覺

OCR(Optical Character Recongnition)即我們通常意義上講的光學字符識別。在HALCON中,OCR常被用來分割區域及讀取識別圖像中的字符含義。

HALCON中提供了一組預先訓練好的字體(在安裝目錄下的ocr文件夾中),這些字體來源於各個領域的大量訓練數據,可識別文檔、製藥、工業產品或點列印,甚至手寫數字文本。此外,HALCON還包括用於OCR-A和OCR-N的預訓練字體,以及基於卷積神經網絡(CNN)的通用字體。

18.1 OCR字符識別

       使用HALCON提供的一種預訓練字體讀取圖中的數字。

FontFile := 'Document_0-9_NoRej'
* 讀取預訓練字體Document_0-9_NoRej,由於沒有指定文件擴展名,因此搜索具有MLP特定擴展名「.omc」或擴展名「.fnt」的文件。
read_ocr_class_mlp (FontFile, OCRHandle)
read_image (Image, 'numbers_scale')
threshold (Image, Region, 0, 125)
connection (Region, Characters)
count_obj (Characters, Number)
dev_set_color ('white')
for i := 1 to Number by 1
select_obj (Characters, SingleChar, i)
* 選擇單個區域、原始圖像和OCR句柄作為輸入,最後返回最佳和第二佳的識別結果和置信度。
do_ocr_single_class_mlp (SingleChar, Image, OCRHandle, 2, Class, Confidence)
endfor

18.2 圖像分割

       對於圖像分割,可以使用的方法很多。常用的有Blob分析、自動文本閱讀器、手動文本閱讀器、通用字符分割等。

18.2.1 Blob分析

       Blob分析包括設定有效ROI、圖像濾波 (mean_image、gauss_filter、binomial_filter、median_image)、點狀列印字符增強(dots_image)、灰度形態等。

(1)Example: hdevelop/Applications/OCR/engraved.hdev

此示例讀取圖中所示的金屬表面上的雕刻文本。

通過使用Blob分析來分割圖像:不能通過簡單的閾值分割來提取字符。相反,簡單的分割只能得到部分字符和產生大量噪聲。使用灰度形態學預處理圖像可以分割出真實字符。

gray_range_rect (Image, ImageResult, 7, 7)
* 圖像取反,字符識別默認為白色背景黑色字體
invert_image (ImageResult, ImageInvert)
threshold (ImageResult, Region, 128, 255)
connection (Region, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 1000,99999)
sort_region (SelectedRegions, SortedRegions,'first_point','true','column')
* 最後識別分割的區域結果
read_ocr_class_mlp (FontName, OCRHandle)
for I := 1 to Number by 1
select_obj (SortedRegions, ObjectSelected, I)
do_ocr_single_class_mlp (ObjectSelected, ImageInvert, OCRHandle, 1, Class, Confidence)
endfor
clear_ocr_class_mlp (OCRHandle)

(2)Example: hdevelop/Applications/OCR/ocrcolor.hdev

此示例提取表單中的字符。一個典型的問題是字符沒有列印在正確的位置,如圖所示。

由於字符列印在線上,不能簡單的通過閾值分割來提取。因此這裡通過字符顏色與表單顏色不同來分割圖像,這裡僅需考慮紅色和綠色通道強度的差異。

threshold (Green, ForegroundRaw, 0, 220)
sub_image (RedReduced, GreenReduced, ImageSub, 2, 128)
mean_image (ImageSub, ImageMean, 3, 3)
binary_threshold (ImageMean, Cluster1, 'smooth_histo', 'dark', UsedThreshold)
difference (Foreground, Cluster1, Cluster2)
concat_obj (Cluster1, Cluster2, Cluster)
opening_circle (Cluster, Opening, 2.5)
* 使用形態學對所選像素進行處理
closing_rectangle1 (NumberRegion, NumberCand, 1, 20)
difference (Image, NumberCand, NoNumbers)
connection (NumberRegion, NumberParts)
intensity (NumberParts, Green, MeanIntensity, Deviation)
expand_gray_ref (NumberParts, Green, NoNumbers, Numbers, 20, 'image', MeanIntensity, 48)
union1 (Numbers, NumberRegion)
connection (NumberRegion, Numbers)
* 由於顏色的變化,因此不能使用背景的灰度值。人為生成一幅圖像,將字符區域灰度值設為0,背景區域灰度值設為255。
paint_region (NoNumbers, Green, ImageOCRRaw, 255, 'fill')
paint_region (NumberRegion, ImageOCRRaw, ImageOCR, 0, 'fill')
* 在人工圖像中執行實際的字符分類。
read_ocr_class_mlp ('Industrial_0-9_NoRej', OCRHandle)
do_ocr_multi_class_mlp (FinalNumbers, ImageOCR, OCRHandle, RecChar, Confidence)
clear_ocr_class_mlp (OCRHandle)

18.2.2 自動文本閱讀器

       自動文本閱讀器非常易於使用,它將分割和識別兩個步驟組合成find_text的一個調用,且無需進行大量的參數調整。simple_reading.hdev和bottle.hdev為熟悉自動文本閱讀器提供了一個很好的起點。

       要使用自動文本閱讀器,必須使用create_text_model_reader創建模型,並將參數Mode設置為'auto'。在這裡,必須傳遞OCR分類器參數。然後可以使用set_text_model_param指定分割參數,並可以使用get_text_model_param查詢。完成後,可以使用find_text讀取文本。該算子根據區域和灰度值特徵選擇候選字符,並使用給定的OCR分類器對其進行驗證。

       如果文本必須匹配某個模式或結構,則可以設置運算符set_text_model_param的參數'text_line_structure',它確定結構,即要檢測的文本的每個字符塊的字符數。

       自動文本閱讀器假定文本方向大致水平。如果文本未水平對齊,則可以在使用find_text之前使用text_line_orientation和rotate_image矯正方向。

       find_text的結果在TextResultID中返回,可以分別使用get_text_result和get_text_object查詢。get_text_result返回分類結果。get_text_object返回自動文本閱讀器分割的字符區域。要刪除結果和文本模型,需分別使用clear_text_result和clear_text_model。

(1)Example: solution_guide/basics/simple_reading.hdev

       此示例程序演示了如何使用預訓練的OCR字體使用自動文本閱讀器識別簡單字符。

* 使用create_text_model_reader創建模型,並將參數Mode設置為'auto'。
create_text_model_reader('auto','Document_09_NoRej',TextModel)
find_text (Image, TextModel, TextResultID)
get_text_result (TextResultID, 'class', Classes)

(2)Example: hdevelop/Applications/OCR/bottle.hdev

這個例子讀取圖中瓶子上的日期。

由於圖像中可見大量文本,因此需要設置文本模型的一些參數以適當地限制讀取結果。

FontName := 'Universal_0-9_NoRej'
create_text_model_reader ('auto', FontName, TextModel)
* 增加最小筆劃寬度以排除日期周圍可見的所有文本
set_text_model_param (TextModel, 'min_stroke_width', 6)
* 設置日期的已知結構以確保僅讀取與該結構匹配的文本
set_text_model_param (TextModel, 'text_line_structure', '2 2 2')
*
find_text (Bottle, TextModel, TextResultID)
* 顯示分割結果
get_text_object (Characters, TextResultID, 'all_lines')
* 顯示讀取結果
get_text_result (TextResultID, 'class', Classes)

18.2.3 手動文本閱讀器

如果要分割雕刻文本或者不能提供合適的OCR分類器,則不能使用自動文本閱讀器。相反,可以在這些情況下使用手動文本閱讀器。

要使用手動文本閱讀器,必須使用create_text_model_reader創建模型,並將參數Mode設置為'manual'。需注意,在這種情況下,不能傳遞OCR分類器。可以與Manual Text Finder一起使用的所有參數的名稱都以'manual_'開頭。

(1)Example: hdevelop/Applications/OCR/find_text_dongle.hdev

此示例演示如何在執行OCR之前使用find_text對加密狗上的點列印字符進行分割。

read_image (Image, 'ocr/dongle_01')
* 讀取OCR分類器文件
read_ocr_class_mlp ('DotPrint_NoRej', OCRHandle)
* 創建文本模型並指定文本屬性
create_text_model_reader ('manual', [], TextModel)
set_text_model_param (TextModel, 'manual_char_width', 24)
set_text_model_param (TextModel, 'manual_char_height', 33)
set_text_model_param (TextModel, 'manual_is_dotprint', 'true')
set_text_model_param (TextModel, 'manual_max_line_num', 2)
set_text_model_param (TextModel, 'manual_return_punctuation', 'false')
set_text_model_param (TextModel, 'manual_return_separators', 'false')
set_text_model_param (TextModel, 'manual_stroke_width', 4)
set_text_model_param (TextModel, 'manual_eliminate_horizontal_lines', 'true')
* 定義文本行結構,''6 1 8'意味著該文本具有由6個,1個和8個字符組成的三個塊。為了定義多個結構,可以將索引號添加到參數名稱。對於第二行,定義了兩個結構,因為有時'/'被分類為分隔符,有時會被分類為字符。
set_text_model_param (TextModel, 'manual_text_line_structure_0', '6 1 8')
set_text_model_param (TextModel, 'manual_text_line_structure_1', '8 10')
set_text_model_param (TextModel, 'manual_text_line_structure_2', '19')
* 為了增加字符識別的準確性,定義了正則表達式,稍後將由do_ocr_word_mlp使用。
TextPattern1 := '(FLEXID[0-9][A-Z][0-9]{3}[A-F0-9]{4})'
TextPattern2 := '([A-Z]{3}[0-9]{5}.?[A-Z][0-9]{4}[A-Z][0-9]{4})'
Expression := TextPattern1 + '|' + TextPattern2
NumImages := 8
for I := 1 to NumImages by 1
read_image (Image, 'ocr/dongle_' + I$'02')
* 圖像預處理,縮減區域範圍。使用scale_image_max改善對比度並且旋轉圖像使字符呈水平。
binary_threshold (Image, Region, 'max_separability', 'dark', UsedThreshold)
opening_rectangle1 (Region, RegionOpening, 400, 50)
erosion_rectangle1 (RegionOpening, RegionOpening, 11, 11)
connection (RegionOpening, ConnectedRegions)
select_shape_std (ConnectedRegions, SelectedRegion, 'max_area', 70)
reduce_domain (Image, SelectedRegion, ImageReduced)
scale_image_max (ImageReduced, ImageScaleMax)
text_line_orientation (SelectedRegion, ImageScaleMax, 30, rad(-30), rad(30), OrientationAngle)
rotate_image (ImageScaleMax, ImageRotate, deg(-OrientationAngle), 'constant')
* 查找文本並顯示每個分割區域的結果
find_text (ImageRotate, TextModel, TextResult)
get_text_result (TextResult, 'manual_num_lines', NumLines)
dev_display (ImageRotate)
for J := 0 to NumLines - 1 by 1
get_text_object (Line, TextResult, ['manual_line',J])
* OCR使用正則表達式更準確地讀取文本。
do_ocr_word_mlp (Line, ImageRotate, OCRHandle, Expression, 3, 5, Class, Confidence, Word, Score)
* 顯示結果
smallest_rectangle1 (Line, Row1, Column1, Row2, Column2)
count_obj (Line, NumberOfCharacters)
dev_set_colored (6)
dev_display (Line)
dev_set_color ('white')
for K := 1 to NumberOfCharacters by 1
select_obj (Line, Character, K)
set_tposition (WindowHandle, Row2[0] + 4, Column1[K - 1])
write_string (WindowHandle, Word{K - 1})
endfor
endfor
if (I < NumImages)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
endif
clear_text_result (TextResult)
endfor
clear_text_model (TextModel)
clear_ocr_class_mlp (OCRHandle)

18.2.4 普通字符分割

對於普通字符分割,可以使用segment_characters獲取包含所有候選字符的區域,然後應用select_characters選擇區域中單個字符的那些部分。或者使用blob分析,最簡單的方法是閾值分割。另一種非常常見的方法是dyn_threshold。

(1)Example: hdevelop/OCR/Segmentation/select_characters.hdev

此示例顯示如何使用專為OCR提供的分割運算符輕鬆分割點列印的旋轉字符。

read_image (Image, 'dot_print_rotated/dot_print_rotated_' + J$'02d')
* 確定文本行的方向,旋轉圖像,使得字符呈水平方向
text_line_orientation (Image, Image, 50, rad(-30), rad(30), OrientationAngle)
rotate_image (Image, ImageRotate, -OrientationAngle / rad(180) * 180, 'constant')
*
* 應用segment_characters和select_characters分割完整的列印區域,然後選擇區域中作為單個字符候選的那些部分。與使用Blob分析的經典分割相比,這裡找到了各個字符的區域,儘管它們仍然由未連接的小區域組成。
segment_characters (ImageRotate, ImageRotate, ImageForeground, RegionForeground, 'local_auto_shape', 'false', 'true', 'medium', 25, 25, 0, 10, UsedThreshold)
select_characters (RegionForeground, RegionCharacters, 'true', 'ultra_light', 60, 60, 'false', 'false', 'none', 'true', 'wide', 'true', 0, 'completion')

18.2.5 基於語法和詞典的OCR結果自動校正

(1)Example: hdevelop/OCR/Neural-Nets/label_word_process_mlp.hdev

此示例讀取圖中描述的"best before"日期。要糾正第一文本行OCR的錯誤識別結果,需使用基於詞典的自動校正。例如,由於字符的相似性,在字符O和數字0之間可能發生錯誤。對於第二文本行,使用正則表達式來確保結果具有正確的格式。

首先,讀取預訓練字體Industrial作為實際OCR。對於文本的上一行,三個預期單詞存儲在使用create_lexicon創建的詞典中,稍後將使用。然後,讀取圖像,生成並對齊用於列印的ROI,並且使用Blob分析提取字符的區域並將其存儲在變量SortedWords中。

* 這個示例展示了如何通過使用正則表達式或允許詞典限制的結果來改進OCR結果。注意,為了演示的目的,分類結果被人為地扭曲了。
read_image (Image, 'label/label_01.png')
read_ocr_class_mlp ('Industrial_NoRej', OCRHandle)
* 創建3個單詞的詞典
create_lexicon ('label', ['BEST','BEFORE','END'], LexiconHandle)
for i := 1 to 9 by 1
read_image (Image, 'label/label_0' + i + '.png')
threshold (Image, Region, 128, 230)
connection (Region, ConnectedRegions)
select_shape (ConnectedRegions, LabelRaw, 'width', 'and', 350, 450)
opening_circle (LabelRaw, LabelOpen, 5)
shape_trans (LabelOpen, Label, 'rectangle2')
* 旋轉文本方向
text_line_orientation (Label, Image, 25, -0.523599, 0.523599, OrientationAngle)
hom_mat2d_identity (HomMat2DIdentity)
hom_mat2d_rotate (HomMat2DIdentity, -OrientationAngle, 0, 0, Deskew)
affine_trans_image (Image, ImageDeskew, Deskew, 'constant', 'false')
affine_trans_region (Label, LabelDeskew, Deskew, 'nearest_neighbor')
smallest_rectangle1 (LabelDeskew, LabelTop, LabelLeft, LabelBottom, LabelRight)
reduce_domain (ImageDeskew, LabelDeskew, ImageOCR)
* 提取特徵區域
var_threshold (ImageOCR, Foreground, 40, 40, 0.8, 10, 'dark')
connection (Foreground, Blobs)
partition_dynamic (Blobs, Split, 21, 40)
select_shape (Split, Characters, ['width','height'], 'and', [10,20], [30,50])
select_shape (Characters, CharactersWords, 'row', 'and', 0, LabelTop + 80)
select_shape (Characters, CharactersDate, 'row', 'and', LabelTop + 80, 600)
* 人為地扭曲分割結果以示範校正效果
move_region (CharactersWords, CharactersWords, 0, 3)
move_region (CharactersDate, CharactersDate, -2, 0)
* 處理文本
sort_region (CharactersWords, SortedWords, 'character', 'true', 'row')
area_center (SortedWords, Area, Row, Column)
Column[|Column|] := 9999
gen_empty_obj (Word)
Text := ''
OriginalText := ''
for j := 1 to |Column| - 1 by 1
select_obj (SortedWords, Character, j)
concat_obj (Word, Character, Word)
* 檢查字符間距以確定單詞的結尾
if (j == |Column| or (Column[j] - Column[j - 1]) > 30)
* 不使用基於詞典的自動校正識別單詞(用於比較)
do_ocr_word_mlp (Word, ImageOCR, OCRHandle, '.*', 1, 5, Class, Confidence, WordText, WordScore)
OriginalText := OriginalText + ' ' + WordText
* 基於詞典校正的單詞識別
do_ocr_word_mlp (Word, ImageOCR, OCRHandle, '<label>', 1, 5, Class, Confidence, WordText, WordScore)
Text := Text + ' ' + WordText
gen_empty_obj (Word)
endif
endfor
sort_region (CharactersDate, SortedDate, 'character', 'true', 'row')
* 不受限制地對數據字符串進行分類(用於比較)
do_ocr_word_mlp (SortedDate, ImageOCR, OCRHandle, '.*', 5, 5, Class, Confidence, OriginalDateText, DateScore)
* 使用正則表達式對數據字符串進行分類
do_ocr_word_mlp (SortedDate, ImageOCR, OCRHandle, '^([0-2][0-9]|30|31)/(0[1-9]|10|11|12)/0[0-5]$', 10, 5, Class, Confidence, DateText, DateScore)
if (i < 9)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
set_display_font (WindowHandle, 20, 'mono', 'true', 'false')
endif
stop ()
endfor
clear_lexicon (LexiconHandle)
clear_ocr_class_mlp (OCRHandle)

18.3 自定義OCR分類器

18.3.1 訓練OCR

下圖顯示了訓練文件生成的過程:首先,必須使用分割方法提取樣本圖像中的字符(參見上文)。必須為每個單個字符分配一個標籤,通過編入輸入或者從文件中讀取字符標籤來完成。然後,將這些區域及其標籤寫入訓練文件中(append_ocr_trainf)。在進行訓練之前,檢查訓練文件的正確性。通過使用與可視化運算符結合的read_ocr_trainf來實現。

注意,還可以訓練自己的系統字體。通過改變和扭曲字符的字體,可以增加每個類的不同訓練樣本的數量,從而提高檢測率。為此,可以使用HDevelop的OCR Assistant的訓練文件工具箱。此外,示例程序generate_system_font.hdev還顯示了如何從系統字體派生訓練數據和OCR分類器。

實際訓練如圖所示。首先,創建一個新的分類器。有四種不同的OCR分類器:神經網絡(多層感知器MLP)分類器,基於支持向量機(SVM)的分類器,基於k近鄰方法(k-NN)的分類器,以及box分類器。

注意,如果要使用自動文本閱讀器進行文本的分割和分類,則必須提供基於MLP的OCR分類器。當只有少量樣本可用時,k-NN具有優勢,但在典型的OCR應用中, MLP和SVM的性能優於k-NN。因此,僅進一步介紹MLP和SVM。

兩個分類器的不同之處如下:MLP分類器在分類上更快,但是對於大型訓練集其訓練速度較慢(與基於SVM的分類器相比)。如果訓練可以離線應用,時間不是關鍵因素,MLP是一個不錯的選擇。基於SVM的分類器比MLP分類器具有更好的識別率,並且在訓練時更快(特別是對於大型訓練集)。但是,與MLP分類器相比,分類過程需要消耗更多時間。

根據所選分類器,使用create_ocr_class_mlp或create_ocr_class_svm創建分類器。然後,使用trainf_ocr_class_mlp或trainf_ocr_class_svm應用訓練。在訓練之後,通常將分類器保存到磁碟以供以後使用(write_ocr_class_mlp或write_ocr_class_svm)。

18.3.2 識別字符

下圖顯示了分類過程。首先,必須使用適當的分割方法提取字符。從文件(read_ocr_class_mlp或read_ocr_class_svm)讀取分類器(字體文件)後,分類器可用於識別。自動文本閱讀器只需一步即可完成分割和分類兩個步驟。

將多個字符傳遞給讀取算子(do_ocr_multi_class_mlp或do_ocr_multi_class_svm)。這裡,對於每個區域,返回相應的標籤和置信度。有時,不僅要獲得置信度最高的字符,還要獲得置信度較低的其它字符。例如,0可能容易被誤認為字母 「O」。算子do_ocr_single_class_mlp和do_ocr_single_class_svm返回此信息。

最後一步,需要將數字或字符組成字符串。這可以通過區域處理運算符來實現。

此外,HALCON還為基於語法和詞典的自動校正提供運算符。例如,可以使用do_ocr_word_mlp而不是do_ocr_multi_class_mlp來查找與正則表達式匹配的字符集,即存儲在詞典中的字符集,這些詞典由create_lexicon創建或由import_lexicon導入。

18.3.3 生成訓練文件

Example: solution_guide/basics/gen_training_file.hdev

下圖顯示了一個訓練圖像,第三行中的字符用作訓練樣本。對於此示例圖像,分割非常簡單,因為字符明顯比背景暗。因此,可以使用閾值分割。

用於訓練的字符行數由變量TrainingLine指定。要選擇此行,首先使用closing_rectangle1將字符組合成水平行。然後通過connection將這些行轉換為其連通域。在所有行中,使用select_obj選擇相對應的行。通過將原始分割和所選行的交集作為輸入,返回訓練的字符。使用sort_region從左到右排序。

TrainingLine := 3
threshold (Image, Region, 0, 125)
closing_rectangle1 (Region, RegionClosing, 70, 10)
connection (RegionClosing, Lines)
select_obj (Lines, Training, TrainingLine)
intersection (Training, Region, TrainingChars)
connection (TrainingChars, ConnectedRegions)
sort_region (ConnectedRegions, SortedRegions, 'first_point', 'true', 'column')

現在,字符可以存儲在訓練文件中。作為準備步驟,刪除可能存在的較舊訓練文件。在所有字符的循環內,選擇單個字符。變量Chars包含字符的標籤Tuple。使用append_ocr_trainf將選定的區域以及圖像和相應的標籤添加到訓練文件中。

Chars := ['0','1','2','3','4','5','6','7','8','9']
TrainFile := 'numbers.trf'
dev_set_check ('~give_error')
delete_file (TrainFile)
dev_set_check ('give_error')
for i := 1 to 10 by 1
select_obj (SortedRegions, TrainSingle, i)
append_ocr_trainf (TrainSingle, Image, Chars[i - 1], TrainFile)
endfor

18.3.4 創建和訓練OCR分類器

Example: solution_guide/basics/simple_training.hdev

準備好訓練文件後,OCR分類器的創建和訓練非常簡單。首先,確定訓練文件和最終字體文件的名稱。建議使用「.trf」作為訓練文件。對於OCR分類器,建議對box分類器使用「.obc」(不再推薦使用),對於神經網絡分類器使用「.omc」,對於基於支持向量機使用 「.osc」。如果在讀取過程中沒有指定擴展名,則對於box或神經網絡分類器,還會搜索擴展名為「.fnt」的文件,這兩個分類器在早期HALCON版本中都很常見。

要創建OCR分類器,需要確定一些參數。最重要的是所有標籤的名稱列表。可以使用read_ocr_trainf_names從訓練文件中輕鬆提取此列表。

TrainFile := 'numbers.trf'read_ocr_trainf_names (TrainFile, CharacterNames, CharacterCount)

另一個重要參數是神經網絡隱藏層中的節點數。在這裡,它被設置為20。根據經驗,該數字應該與標籤的數量相同。除了這兩個參數之外,其它參數選用默認值用於create_ocr_class_mlp。使用trainf_ocr_class_mlp進行訓練,參數也使用默認值。

NumHidden := 20
create_ocr_class_mlp (8, 10, 'constant', 'default', CharacterNames, NumHidden, 'none', 1, 42, OCRHandle)
trainf_ocr_class_mlp (OCRHandle, TrainFile, 200, 1, 0.01, Error, ErrorLog)
* 最後,將分類器(字體文件)存儲到磁碟並釋放內存。
FontFile := 'numbers.omc'
write_ocr_class_mlp (OCRHandle, FontFile)
clear_ocr_class_mlp (OCRHandle)

注意,對於更複雜的OCR分類器,尤其是訓練數據包含非常嘈雜和變形的樣本,則建議創建權重正則化的基於MLP的OCR分類器(參見set_regularization_params_ocr_class_mlp)。這增強了分類器的泛化能力並且防止對單個訓練樣本的過度擬合。

如果為自動文本閱讀器創建了OCR分類器,建議另外使用set_rejection_params_ocr_class_mlp定義拒絕類,這有助於區分字符與複雜的背景。

18.3.5 具有正則權重和拒絕類的OCR分類器

也可以創建和訓練具有正則權重和拒絕類的分類器。

正則權重可以提升分類性能:

• 如果未經正則的MLP出錯,則錯誤結果的置信度通常會非常高。

• 如果正則化的MLP出錯,則返回直觀的置信度。能表明更好的泛化能力。

可以使用運算符設置和查詢正則化的參數

• set_regularization_params_ocr_class_mlp和

• get_regularization_params_ocr_class_mlp

如何設置用於創建和訓練具有正則化的分類器的參數,如以下HDevelop示例所示:

• 示例regularized_ocr_mlp.hdev創建具有嚴重失真的測試樣本,這些失真程度遠遠超出訓練失真的範圍,以測試MLP和正則化MLP的泛化能力。

• 示例class_mlp_regularization.hdev顯示了使用MLP規範二維數據的效果。

拒絕類可能是有用的,因為它返回圖像中無法成功讀取的符號,因為它們不是符號,有可能是噪聲,或者是其它存在的問題。

可以使用運算符設置和查詢拒絕類的參數

• set_rejection_params_ocr_class_mlp和

• get_rejection_params_ocr_class_mlp。

示例程序set_rejection_params_class_mlp.hdev顯示了如何使用MLP的拒絕類來分類二維數據。

18.4 擴展內容

18.4.1 組合符號

一些字符和符號由多個子符號組成,如「i」,「%」或「!」。對於OCR,這些子符號必須組合成單個區域。如果使用segment_characters和select_characters進行字符分割,則會自動組合子符號。否則,就需要通過在閾值處理後調用closing_rectangle1來組合它們,結構元素通常使用較小的寬度和較大的高度。在調用connection以分割字符後,使用intersection來獲取原始分割(輸入參數2),同時輸入connection中的連通域(輸入參數1)。

18.4.2 圓形列印字符

在某些情況下,符號不是水平列印的,而是沿著圓弧列印,例如在CD上列印。為了讀取它們,提取相應圓的(虛擬)中心和半徑。使用polar_trans_image_ext展開圖像。要將在展開的圖像中獲得的區域投影回原始圖像,可以使用polar_trans_region_inv。

18.4.3 OCR 特徵

HALCON為OCR提供了許多不同的功能,其中大部分僅供高級使用。在大多數情況下,建議使用功能組合「default」。此組合基於字符周圍矩形內的灰度值。在不能使用字符的背景的情況下,例如,如果它因紋理而變化,則特徵'pixel_binary','ratio'和'anisometry'是良好的組合。這裡,僅使用區域,忽略基礎灰度值。

18.5 預訓練的ORC字體

以下部分將簡要介紹HALCON提供的預訓練OCR字體。可以在安裝HALCON的文件夾的子目錄ocr中訪問它們。預訓練字體是使用在亮背景下的暗字符進行訓練的。如果要使用提供的字體讀取暗背景下的亮字符,可以使用invert_image反轉圖像,如果效果不好,則可以應用gen_image_proto設為淺灰色值,然後overpaint_region將灰度值設置為0來預處理圖像。

預訓練字體是使用編碼Windows-1252的字符進行訓練的。因此,ASCII代碼大於127的字符符號('e','£','¥')的外觀可能與預期的外觀不同,具體取決於系統的字符編碼。在這種情況下,應根據其ASCII碼檢查分類字符,即'e'為128,'£'為163,'¥'為165。

18.5.1 具有正則權重和拒絕類的預訓練字體

所有預訓練的OCR字體都有兩個版本。以_NoRej結尾的字體名稱具有正則化權重但沒有拒絕類,以_Rej結尾的字體名稱具有正則化權重及拒絕類。由於正則化,預訓練的OCR字體提供了更有意義的置信度。使用拒絕類的字體,可以區分字符與雜亂背景。帶有拒絕類的字體返回ASCII Code 26。

18.5.2 即用型OCR字體的命名法

OCR字體的內容由其名稱描述。名稱以組名開頭,例如Document或DotPrint,後跟OCR字體中包含的符號集的指示符。指標的含義如下:

• 0-9:OCR字體包含數字0到9。

• A-Z:OCR字體包含大寫字符A到Z.

• +:OCR字體包含特殊字符。特殊字符列表與單個OCR字體略有不同。

• _NoRej:OCR字體沒有拒絕類。

• _Rej:OCR字體有拒絕類。

如果OCR字體的名稱不包含任何上述指示符或僅後跟指示符_NoRej或_Rej,通常,OCR字體包含數字0到9,大寫字符A到Z,小寫字符a到 z,和特殊字符。某些OCR字體不包含小寫字符(例如,DotPrint)。

18.5.3 預訓練字體』Document』

』Document』可用於讀取以Arial,Courier或Times New Roman等字體列印的字符。這些是用於列印文檔或字母的典型字體。請注意,無法區分字體Arial的字符I和l。這意味著l可能被誤認為是I,反之亦然。

可用的特殊字符:- = + < > . # $ % & ( ) @ * e £ ¥

18.5.4 預訓練字體 』DotPrint』

『DotPrint』可用於讀取用點式印表機列印的字符。它不包含小寫字符。

可用的特殊字符:- / . * :

18.5.5 預訓練字體 』HandWritten_0-9』

『HandWritten_0-9』可用於讀取手寫數字。它包含數字0-9。

可用的特殊字符:無

18.5.6 預訓練字體 』Industrial』

『Industrial』可用於讀取以Arial,OCR-B或其他sans-serif字體等列印的字符。例如,這些字體通常用於列印標籤。

可用的特殊字符:- / + . $ % * e £ ¥

18.5.7 預訓練字體 』OCR-A』

『OCR-A』可用於讀取以字體OCR-A列印的字符。

可用的特殊字符:- ? ! / \{} = + < > . # $ % & ( ) @ * e £ ¥

18.5.8 預訓練字體 』OCR-B』

『OCR-B』可用於讀取以字體OCR-B列印的字符。

可用的特殊字符:- ? ! / \{} = + < > . # $ % & ( ) @ * e £ ¥

18.5.9 預訓練字體 』Pharma』

『Pharma』可用於讀取以Arial,OCR-B等字體列印的字符,以及製藥行業通常使用的其它字體(見圖18.18)。此OCR字體不包含小寫字符。

可用的特殊字符:- / . ( ) :

18.5.10 預訓練字體 』SEMI』

『SEMI』可用於讀取以SEMI字體列印的字符,該字體由易於彼此區分的字符組成。它有一組有限的字符,可以在圖18.19中看到。此OCR字體不包含小寫字符。

可用的特殊字符:- .

18.5.11 預訓練字體 』Universal』

『Universal』可用於讀取各種不同的字符。這種基於CNN訓練的字體的基於 『』Document』,「DotPrint」,「SEMI」和「Industrial』」等字符。

可用的特殊字符:- / = + : < > . # $ % & ( ) @ * e £ ¥

————————————————

版權聲明:本文為CSDN博主「Mr.Devin」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/IntegralforLove/article/details/83756956

標籤:深度學習halcon

相關焦點

  • 用Transformer實現OCR字符識別!
    本文將採用一個單詞識別任務數據集,講解如何使用transformer實現一個簡單的OCR文字識別任務,並從中體會transformer是如何應用到除分類以外更複雜的CV任務中的。等)其中 ocr_by_transformer.py 為主要的訓練腳本,其依託 train_utils.py 和 transformer.py 兩個文件構建 transformer 來完成字符識別模型的訓練一、數據集簡介與獲取本文使用的數據集基於ICDAR2015 Incidental Scene Text 中的 Task 4.3
  • 用python和Tesseract實現光學字符識別(OCR)
    在上周的博客中我們學會了安裝光學字符識別程序Tesseract,以及應用Tesseract程序來測試和評估OCR引擎在一小部分示例圖像上的性能。在本節中,我們將嘗試使用以下過程完成三個示例圖像的OCR識別:    1、首先,對每幅圖運行Tesseract二進位程序;    2、然後運行ocr.py(在通過Tesseract發送之前執行預處理操作)    3、最後,我們將比較這兩種方法的結果,並記錄錯誤的地方。我們的第一個例子是關於「noisy」的圖像。
  • 卷積神經網絡 - CNN 用一維心電圖信號說明
    就卷積神經網絡 (CNN) 而言,這種特殊算法在定義深度學習 (DL) 等最複雜和最高級算法的架構方面發揮著重要作用。卷積神經網絡我們已經在下面的文章中詳細討論了卷積神經網絡 (CNN),其中包含帶有 Python 代碼的圖像處理領域(與計算機視覺相關)。
  • 超輕量級中文OCR,支持豎排文字識別、ncnn推理,總模型僅17M
    來源 | AI科技大本營光學字符識別(OCR)技術已經得到了廣泛應用。
  • 基於卷積神經網絡的遙感圖像目標檢測與識別
    卷積神經網絡CNN(Convolutional Neural Network)憑藉其包含的深層語義特徵在計算機視覺領域取得了巨大的成功,近年來也越來越多的被應用到遙感圖像目標檢測與識別任務中。    然而,現有的基於卷積祌經網絡的遙感圖像目標檢測方法依賴大量bounding box數據(位置信息數據)進行訓練,需要耗費大量人工標註成本,同時由於遙感圖像的目標樣本數量有限,不足以支撐大規模訓練;另外現有的基於卷積神經網絡的遙感圖像目標識別方法僅考慮網絡的深層語義特徵,導致識別性能達到瓶頸。為解決上述問題,本文基於卷積神經網絡對遙感圖像目標檢測與識別算法進行研究。
  • Python圖像處理之圖片文字識別(OCR)
    它可以通過訓練識別出任何字體(只要這些字體的風格保持不變就可以),也可以識別出任何Unicode 字符。Tesseract的安裝與使用   Tesseract的Windows安裝包下載地址為: http://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-setup-4.00.00dev.exe ,下載後雙擊直接安裝即可。
  • Tesseract-OCR-v5.0中文識別,訓練自定義字庫,提高圖片的識別效果
    要注意:Tesseract-OCR的安裝目錄要包含識別中文的字符集chi_sim.traineddata,可以在GitHub下載https://github.com/tesseract-ocr/tessdata
  • Python項目實戰篇——常用驗證碼標註&識別(CNN神經網絡模型訓練/測試/部署)
    一、前言    今天給大家分享的實戰項目是常用驗證碼標註&識別,前面三篇文章講解了文章的創作靈感、需求分析和實現思路、數據採集/預處理/字符圖切割等知識、高效率數據標註等知識,分別是以下文章:Python項目實戰篇——常用驗證碼標註和識別(需求分析和實現思路)Python項目實戰篇——常用驗證碼標註&識別(數據採集/預處理/字符圖切割)
  • 本周優秀開源項目分享:基於yolov3的輕量級人臉檢測、增值稅發票OCR識別 等8大項目
    從藝術品中提取的人臉圖像數據集MetFaces是從藝術品中提取的人臉圖像數據集,最初是我們在以下方面的工作之一:用有限的數據訓練生成對抗網絡,使用flask微服務架構,識別type:增值稅電子普通發票,增值稅普通發票,增值稅專用發票;識別欄位為:發票代碼、發票號碼、開票日期、校驗碼、稅後金額等。
  • cnocr:用來做中文OCR的Python3包,裝上就能用!
    目前兩個階段分別包含以下的模型:局部編碼模型(emb model)序列編碼模型(seq model)lstm:兩層的LSTM網絡;gru:兩層的GRU網絡;fc:兩層的全連接網絡。cnocr目前包含以下可直接使用的模型,訓練好的模型都放在 cnocr-models 項目中,可免費下載使用:
  • Python OCR工具pytesseract詳解
    安裝pytesseract文字識別小例子獲取文字位置信息多語言識別    使用方法    訓練數據OCR選項    圖片分割模式(PSM)    OCR引擎模式(OEM)方向及語言檢測OSD提取數字字符白名單字符黑名單格式轉換引言
  • 【OCR技術實踐】(六)文本數據合成方法
    前言對於文本識別,主要存在的一些困難是:①文字多樣,各種字體和風格的文字都可能存在;②生僻字問題,字符不均衡;③相似字問題。這也造成訓練一個比較魯棒的識別模型,數據是十分重要的,需要儘可能地覆蓋多樣性。在實際應用中,由於中文字符的特殊性,數據難以採集,特別是非常用字符,這也造成了文本識別中,訓練數據很難覆蓋到所有場景,而且訓練素材的標註成本太高,所以需要使用合成、增強等低成本方法獲取更多的數據。
  • 用Keras和CNN建立模型,識別神奇寶貝(附代碼)
    如果你對於神奇寶貝不了解,你可以把神奇寶貝圖鑑想像成一個可以識別神奇寶貝(一個長得像動物、存在於在神奇寶貝世界的生物)的智慧型手機app。當然你也可以換成你自己的數據,我只是覺得很有趣並且在做一件很懷舊的事情。想要知道如何在你自己的資料庫中用Keras和深度學習訓練一個卷積神經網絡,繼續往下讀就行了。
  • python人工智慧-圖像識別
    pytesseract:圖像識別庫。則在命令行執行如下命令:pip install pytesseractpip install PIL這時候我們去運行上面的代碼會發現如下錯誤:錯誤提示的很明顯:No such file or directory :"tesseract"這是因為我們沒有安裝tesseract-ocr
  • CNN系列-神經網絡模型結構設計的演變和理解
    其實在此之前98年LeNet5用於手寫數字識別的卷積神經網絡已是完備的cnn網絡,如conv層、pooling層、fc層、激活函數等;為什麼Alexnet卻被譽為第一個真正意義上的深度網絡呢?我理解就是因為它提出了Relu、Dropout等方法另外基於GPU硬體的加持,讓具有龐大參數量的深度網絡訓練成為可能。所以AlexNet被大家譽為第一個真正意義上的深度網絡。
  • Python圖片識別庫Tesseract實戰
    但是,Python中你可以輕易的使用ocr(光學字符識別)技術.對圖片元素中的文字進行提取.從而解決技術難題.具體需要以下3步:①安裝Tesseract-ocr服務②安裝pytesseract-python驅動庫③識別圖片①Tesseract是一款由Google贊助的開源OCR。
  • 用Python開發截圖識別OCR小工具
    今天,我們就來做一款實時截圖識別的小工具。顧名思義,運行程序時,可以實時的把你截出來的圖片中的文字識別出來。下次,當你想要複製「百度文庫」中的內容時,不妨試試這個程序。效果預覽其中「f1」是截圖的快捷鍵,「ctrl+c」是把截圖保存到剪貼板的快捷鍵。
  • Python 中文圖片OCR
    有個需求,需要從一張圖片中識別出中文,通過python來實現,這種這麼高大上的黑科技我們普通人自然搞不了,去github找了一個似乎能滿足需求的開源庫
  • PP-OCR:實用超輕量級文本識別系統設計詳解
    算法架構典型的OCR系統,按照流程分為兩大支:1)先檢測後識別(detection then recognition);2)端到端識別(end to end text spotting);作者們選擇傳統的先文本檢測後文本識別的流程,另外對於檢測到的文本
  • TensorFlow 基礎 - 3 卷積神經網絡
    卷積神經網絡抓住它的核心思路,即通過卷積操作縮小了圖像的內容,將模型注意力集中在圖像特定的、明顯的特徵上。(簡而言之,'過擬合'發生在網絡模型從訓練集中學習到的結果非常好,但它太狹隘了,只能識別訓練數據,而在看到其他數據時效果不佳。舉個例子,如果我們一輩子只看到紅色的鞋子,那麼當我們看到一雙藍色的麂皮鞋可能會感到迷惑.再舉一例,應試教育往往使得學生只對做過的題目有很好的正確率,但對真實的問題卻錯誤率很高)