halcon——條碼定位與識別(一維碼)


引言

條碼識別的應用大多數在物流行業中(需要識別的條碼一般在快遞包裹中),對於一維碼的識別,halcon有自帶條碼識別算子create_bar_code_model和find_bar_code 。而快遞標簽處有很多的文字,符號和邊框,增大了定位的難度。,因此有時也有檢測不到條碼的情況。針對這一現象,本篇就來深度分析一下如何更好的去識別一維碼。


 一,相關算子分析

  • create_bar_code_model(創建一維碼模型)

create_bar_code_model ([], [], BarCodeHandle) 
參數一//輸入   需要調整的參數名稱(為[]表示暫時不設置)
參數二//需要調整的該參數的值。 
參數三// 返回的條碼模板句柄 
  • set_bar_code_param(對模型設置參數)
set_bar_code_param( BarCodeHandle, GenParamNames, GenParamValues )

BarCodeHandle(in//模型句柄
GenParamNames(in//參數名稱
GenParamValues (in//參數值

  • find_bar_code (識別一維碼)

find_bar_code(Image ,SymbolRegions ,BarCodeHandle, CodeType , DecodedDataStrings)

參數列表:
Image //輸入圖像
SymbolRegions//檢測到的條形碼區域(輸出)
BarCodeHandle//    條形碼句柄
CodeType//    條形碼類型
DecodedDataStrings//識別結果(輸出)

二,提高解碼能力的其他措施

(1)圖像預處理(增強條碼)

  • 對比度太低:scale_image(或使用外部程序scale_image_range),增強圖像的對比度。
  • 圖像模糊:emphasize銳化圖像,使條碼看起來更清晰。
  • 深色背景上讀取淺色條碼:invert_image反轉圖像。

(2)如果整張圖信息太多,則可以先把條碼區域挖出來,使用reduce_domain和crop_domain算子,這樣不僅可以降低解碼難度,還可以減少解碼時間。也可使用decode_bar_code_rectangle2在指定的矩形區域內解碼。

(3)當條碼很密或者很小的時候,可以嘗試用zoom_image_factor放大了條碼圖像。

(4)find_bar_code中將“CodeType”設置為“auto”可以讀取多種類型的條碼,但是會增加運行時間,且可能會降低解碼的可靠性。最好只掃描預知的條形碼類型。

三,如何在圖像提取條碼區域

以快遞上的一維碼為例,由於快遞標簽處有很多的文字,符號和邊框,增大了定位的難度。(如下圖)而且有很多噪聲的影響。

 halcon實現:


 1,讀入圖像,提取輪廓


 有兩種方法:

  1. 基於邊緣提取
  2. blob分析
read_image (Image, 'C:/Users/86175/Desktop/4.png')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width/2, Height/2, 'black', WindowHandle)
dev_display (Image)
rgb1_to_gray (Image, GrayImage)

*第一種邊緣提取初步提取輪廓
laplace_of_gauss(GrayImage, ImageLaplace, 2)//拉布拉斯算子
threshold(ImageLaplace, Region3, 5, 127)
skeleton(Region3, Skeleton3)
connection (Skeleton3, ConnectedRegions2)
select_shape (ConnectedRegions2, SelectedRegions, ['area','width','height'], 'and', [0,0,0], [220,80,200])

*第二種Blob分析法初步提取條碼
threshold (GrayImage, Regions, 7, 107)
connection (Regions, ConnectedRegions)

二者提取效果差不多,但是考慮到Blob分析法可能對相機像素有較大的要求,否則二值化后可能提取不出條碼線,個人覺得用邊緣提取的方式較穩定。


 2,篩選條碼區域


*通過面積和矩形度篩選
select_shape (ConnectedRegions, SelectedRegions1, 'area', 'and', 60, 1500)
select_shape_std (SelectedRegions1, SelectedRegions, 'rectangle2', 60)

*提取輪廓
union1 (SelectedRegions, RegionUnion)
skeleton (RegionUnion, Skeleton4)
gen_contours_skeleton_xld (Skeleton4, Contours1, 1, 'filter')
*通過輪廓長度過濾小噪聲
select_contours_xld (Contours1, SelectedContours, 'contour_length', 30, 200, -0.5, 0.5)


 3,擬合直線,進一步篩選


*因為條碼都是直線,可以通過角度相同的直線分割條碼
*擬合直線
fit_line_contour_xld (SelectedContours, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist1)
*畫擬合線
gen_region_line (RegionLines1, RowBegin, ColBegin, RowEnd, ColEnd)
*在0~-180°里每-30°查找一次條碼
for i:=-1 to -150 by -30
    
    select_shape (RegionLines1, SelectedRegions3, 'phi', 'and', rad(i-30),  rad(i))
    count_obj (SelectedRegions3, Number)
    if(Number>12)
        union1 (SelectedRegions3, RegionUnion1)
        area_center (RegionUnion1, Area1, Row, Column)
        orientation_region (RegionUnion1, Phi)
        if(Phi>rad(90))
            Phi:=Phi-rad(180)
        endif
        if(Phi<-rad(90))
            Phi:=rad(180)+Phi
        endif
        vector_angle_to_rigid (Row, Column, Phi, Row, Column,rad(0), HomMat2D)
        affine_trans_region (RegionUnion1, RegionAffineTrans1, HomMat2D, 'nearest_neighbor')
        affine_trans_image (GrayImage, ImageAffineTrans, HomMat2D, 'constant', 'false')   
        closing_rectangle1 (RegionAffineTrans1, RegionClosing, 80, 2)
        connection (RegionClosing, ConnectedRegions1)
        select_shape (ConnectedRegions1, SelectedRegions4, 'area', 'and', 2954.26, 50000)
        shape_trans (SelectedRegions4, RegionTrans, 'rectangle2')
        region_features (RegionTrans, 'width', w)
        region_features (RegionTrans, 'height', h)
        if(w/h<2.5 or w/h>10)
            continue
        endif
        reduce_domain (ImageAffineTrans, RegionTrans, ImageReduced1)
        threshold (ImageReduced1, Regions1, 160, 254)
        area_center (Regions1, Area, Row1, Column1)
        threshold (ImageReduced1, Regions2, 0, 120)
        area_center (Regions2, Area2, Row2, Column2)
        if(Area>Area2)
            if(Area/Area2>2)
                continue
            endif
        endif
        if(Area2>Area)
            if(Area2/Area>2)
                continue
            endif
        endif
        dilation_circle (RegionTrans, RegionDilation, 6)
        reduce_domain (ImageAffineTrans, RegionDilation, ImageReduced)
    endif
endfor

 

 

參考博文:(2條消息) Halcon條碼定位算法(一維碼)_三元熒的博客-CSDN博客


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM