第18章 光學字元識别_OCR
OCR(Optical Character Recongnition)即我們通常意義上講的光學字元識别。在HALCON中,OCR常被用來分割區域及讀取識别圖像中的字元含義。
HALCON中提供了一組預先訓練好的字型(在安裝目錄下的ocr檔案夾中),這些字型來源于各個領域的大量訓練資料,可識别文檔、制藥、工業産品或點列印,甚至手寫數字文本。此外,HALCON還包括用于OCR-A和OCR-N的預訓練字型,以及基于卷積神經網絡(CNN)的通用字型。
18.1 OCR字元識别
使用HALCON提供的一種預訓練字型讀取圖中的數字。

- 讀取預訓練字型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)
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)
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')
- 顯示讀取結果
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 := '(FLEXID0-9[0-9]{3}[A-F0-9]{4})'
TextPattern2 := '([A-Z]{3}[0-9]{5}.?A-Z{4}A-Z{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)
clear_text_model (TextModel)
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, '', 1, 5, Class, Confidence, WordText, WordScore)
Text := Text + ' ' + WordText
gen_empty_obj (Word)
endif
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|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')
set_display_font (WindowHandle, 20, 'mono', 'true', 'false')
stop ()
clear_lexicon (LexiconHandle)
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)
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從訓練檔案中輕松提取此清單。
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)
注意,對于更複雜的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 £ ¥
Symbol set
Name of OCR font
with rejection class
without rejection class
0-9, A-Z, a-z, special characters
Document_Rej
Document_NoRej
A-Z, special characters
Document_A-Z+_Rej
Document_A-Z+_NoRej
0-9
Document_0-9_Rej
Document_0-9_NoRej
0-9, A-Z
Document_0-9A-Z_Rej
Document_0-9A-Z_NoRej
18.5.4 預訓練字型 ’DotPrint’
‘DotPrint’可用于讀取用點式列印機列印的字元。它不包含小寫字元。
可用的特殊字元:- / . * :
0-9, A-Z, special characters
DotPrint_Rej
DotPrint_NoRej
DotPrint_A-Z+_Rej
DotPrint_A-Z+_NoRej
DotPrint_0-9_Rej
DotPrint_0-9_NoRej
0-9, special characters
DotPrint_0-9+_Rej
DotPrint_0-9+_NoRej
DotPrint_0-9A-Z_Rej
DotPrint_0-9A-Z_NoRej
18.5.5 預訓練字型 ’HandWritten_0-9’
‘HandWritten_0-9’可用于讀取手寫數字。它包含數字0-9。
可用的特殊字元:無
HandWritten_0-9_Rej
HandWritten_0-9_NoRej
18.5.6 預訓練字型 ’Industrial’
‘Industrial’可用于讀取以Arial,OCR-B或其他sans-serif字型等列印的字元。例如,這些字型通常用于列印标簽。
可用的特殊字元:- / + . $ % * e £ ¥
Industrial_Rej
Industrial_NoRej
Industrial_A-Z+_Rej
Industrial_A-Z+_NoRej
Industrial_0-9_Rej
Industrial_0-9_NoRej
Industrial_0-9+_Rej
Industrial_0-9+_NoRej
Industrial_0-9A-Z_Rej
Industrial_0-9A-Z_NoRej
18.5.7 預訓練字型 ’OCR-A’
‘OCR-A’可用于讀取以字型OCR-A列印的字元。
可用的特殊字元: - ? ! / {} = + < > . # $ % & ( ) @ * e £ ¥
OCRA_Rej
OCRA_NoRej
OCRA_A-Z+_Rej
OCRA_A-Z+_NoRej
OCRA_0-9_Rej
OCRA_0-9_NoRej
OCRA_0-9A-Z_Rej
OCRA_0-9A-Z_NoRej
18.5.8 預訓練字型 ’OCR-B’
‘OCR-B’可用于讀取以字型OCR-B列印的字元。
可用的特殊字元:- ? ! / {} = + < > . # $ % & ( ) @ * e £ ¥
OCRB_Rej
OCRB_NoRej
OCRB_A-Z+_Rej
OCRB_A-Z+_NoRej
OCRB_0-9_Rej
OCRB_0-9_NoRej
OCRB_0-9A-Z_Rej
OCRB_0-9A-Z_NoRej
0-9, A-Z, + and <
OCRB_passport_Rej
OCRB_passport_NoRej
18.5.9 預訓練字型 ’Pharma’
‘Pharma’可用于讀取以Arial,OCR-B等字型列印的字元,以及制藥行業通常使用的其它字型(見圖18.18)。此OCR字型不包含小寫字元。
可用的特殊字元: - / . ( ) :
Pharma_Rej
Pharma_NoRej
Pharma_0-9_Rej
Pharma_0-9_NoRej
Pharma_0-9+_Rej
Pharma_0-9+_NoRej
Pharma_0-9A-Z_Rej
Pharma_0-9A-Z_NoRej
18.5.10 預訓練字型 ’SEMI’
‘SEMI’可用于讀取以SEMI字型列印的字元,該字型由易于彼此區分的字元組成。它有一組有限的字元,可以在圖18.19中看到。此OCR字型不包含小寫字元。
可用的特殊字元: - .
SEMI_Rej
SEMI_NoRej
18.5.11 預訓練字型 ’Universal’
‘Universal’可用于讀取各種不同的字元。這種基于CNN訓練的字型的基于 ‘’Document’,“DotPrint”,“SEMI”和“Industrial’”等字元。
可用的特殊字元:- / = + : < > . # $ % & ( ) @ * e £ ¥
Universal_Rej
Universal_NoRej
Universal_A-Z+_Rej
Universal_A-Z+_NoRej
Universal_0-9_Rej
Universal_0-9_NoRej
Universal_0-9+_Rej
Universal_0-9+_NoRej
Universal_0-9A-Z_Rej
Universal_0-9A-Z_NoRej
Universal_0-9A-Z+_Rej
Universal_0-9A-Z+_NoRej
作者:Mr.Devin
來源:CSDN
原文:
https://blog.csdn.net/IntegralforLove/article/details/83756956版權聲明:本文為部落客原創文章,轉載請附上博文連結!