Halcon 缺陷检测

news2024/11/18 21:41:37

文章目录

  • 开闭运算,腐蚀膨胀的亮点问题
  • 灰度图像的开闭运算,腐蚀膨胀的亮点问题
  • 算子
    • 二值化算子
  • Halcon blob+特征处理的方法检测缺陷
  • Halcon Blob+特征+差分的方法检测缺陷
  • Halcon 极坐标变换(环形先转换坐标)+blob+特征
  • Halcon Blob+局部二值化+特征提取缺陷检测
  • Halcon blob+灰度差分+特征缺陷检测案例
  • Halcon 定位(blob求角度)+特征
  • Halcon 定位(模板匹配)+测量
  • Halcon 拟合方法的求缺陷
  • Halcon OCV光学字符检测
    • OCV 模板创建
    • OCV 字符质量缺陷识别
    • OCV 字符缺陷检测展示案例

开闭运算,腐蚀膨胀的亮点问题

开运算先进行腐蚀操作再进行膨胀操作,通常可以消除小的亮点(暗点变多)区域并使边缘更加清晰,因此亮点通常会减少。而闭运算先进行膨胀操作再进行腐蚀操作,可以填补亮点中间的空洞并使其更加连通,因此亮点通常会增多(暗点减少)。
腐蚀和膨胀也是形态学处理中常用的基本操作,它们分别可以缩小或消除亮点区域(腐蚀),或扩大或连接亮点区域(膨胀)。在进行开运算时,腐蚀操作会消除较小的亮点区域,膨胀操作会尝试连接亮点并填充它们之间的空隙;在进行闭运算时,膨胀操作会连接较小的亮点区域并填充它们之间的空隙,腐蚀操作会消除边缘部分使得亮点更加连通和光滑。

灰度图像的开闭运算,腐蚀膨胀的亮点问题

对于灰度图像进行开闭运算时,腐蚀和膨胀操作的影响与二值图像略有不同。在灰度图像中,腐蚀和膨胀操作会改变亮度值而不仅仅是亮点的数量。

在开运算中,先进行腐蚀操作再进行膨胀操作。腐蚀操作会使亮区域的亮度值降低,从而减小亮点的尺寸和强度(暗点变多)。然后,膨胀操作会试图恢复亮区域的亮度值,但由于先前的腐蚀操作的影响,亮点可能不会完全恢复到原始的尺寸和强度。因此,在灰度图像中进行开运算可能会导致亮点数量减少,并且亮点的尺寸和强度也可能减小。

相反,在闭运算中,先进行膨胀操作再进行腐蚀操作。膨胀操作会使亮区域的亮度值增加,从而增大亮点的尺寸和强度(暗点减少)。然后,腐蚀操作会试图消除边缘部分并使亮点更加连通和光滑。因此,在灰度图像中进行闭运算通常会导致亮点数量增多,并且亮点的尺寸和强度也可能增加。

算子

二值化算子

Halcon blob+特征处理的方法检测缺陷

在这里插入图片描述

* This example demonstrates a quality inspection on hazelnut wavers.
* Using the morphology tools the waver is extracted and examined
* according to a few shape features like Rectangularity and AreaHoles.
* This program also shows the use of the operator area_holes.
* 
read_image (Image, 'food/hazelnut_wafer_01')
dev_close_window ()
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
dev_update_window ('off')
dev_set_line_width (3)
dev_set_draw ('margin')
set_display_font (WindowHandle, 20, 'mono', 'true', 'false')
* 
for Index := 1 to 24 by 1
    read_image (Image, 'food/hazelnut_wafer_' + Index$'.02')
    binary_threshold (Image, Foreground, 'smooth_histo', 'light', UsedThreshold)
    opening_circle (Foreground, FinalRegion, 8.5)
    * 求空洞面积
    area_holes (FinalRegion, AreaHoles)
    * 求矩形度量
    rectangularity (FinalRegion, Rectangularity)
    dev_display (Image)
    * 如果空洞面积>300 并且矩形度<0.92 不合格
    if (AreaHoles > 300 or Rectangularity < 0.92)
        dev_set_color ('red')
        Text := 'Not OK'
    else
        dev_set_color ('forest green')
        Text := 'OK'
    endif
    dev_display (FinalRegion)
    disp_message (WindowHandle, Text, 'window', 12, 12, '', 'false')
    if (Index < 24)
        disp_continue_message (WindowHandle, 'black', 'true')
        stop ()
    endif
endfor

在这里插入图片描述

Halcon Blob+特征+差分的方法检测缺陷

闭运算是先进行膨胀操作,再进行腐蚀操作,通常用于填充图像中的小孔洞或连接断开的区域。闭运算可以平滑和闭合图像中的对象边界。
开运算是先进行腐蚀操作,再进行膨胀操作,通常用于去除图像中的小尖峰或细小的对象。开运算可以平滑和消除图像中的噪点。

在这里插入图片描述

* fin.hdev: Detection of a fin
* 
*  采集
dev_update_window ('off')
read_image (Fins, 'fin' + [1:3])
get_image_size (Fins, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width[0], Height[0], 'black', WindowID)
set_display_font (WindowID, 14, 'mono', 'true', 'false')
for I := 1 to 3 by 1
    select_obj (Fins, Fin, I)
    dev_display (Fin)
    * 分割
    *二值化
    binary_threshold (Fin, Background, 'max_separability', 'light', UsedThreshold)
    dev_set_color ('blue')
    dev_set_draw ('margin')
    dev_set_line_width (4)
    dev_display (Background)
    disp_continue_message (WindowID, 'black', 'true')
    stop ()
   
    * 使用闭运算把圆形填充,先膨胀在腐蚀
    closing_circle (Background, ClosedBackground, 250)
    dev_set_color ('green')
    dev_display (ClosedBackground)
    disp_continue_message (WindowID, 'black', 'true')
    stop ()
    * 将闭运算得到的图像和原图像做差
    difference (ClosedBackground, Background, RegionDifference)
    * 差值区域做开运算去除噪点,先腐蚀在鹏展
    opening_rectangle1 (RegionDifference, FinRegion, 5, 5)
    dev_display (Fin)
    dev_set_color ('red')
    dev_display (FinRegion)
    * 特征提取
    * 获取中心区域的面积,和行列坐标
    area_center (FinRegion, FinArea, Row, Column)
    if (I < 3)
        disp_continue_message (WindowID, 'black', 'true')
        stop ()
    endif
endfor

在这里插入图片描述

Halcon 极坐标变换(环形先转换坐标)+blob+特征

Halcon 圆环上orc字体识别
在这里插入图片描述

* This example checks bottle necks for defects.
* First, the bottle is detected with basic morphology,
* edge detection and circle fitting.
* Then, the neck area is transformed with a polar transformation.
* After that, in the transformed image a dynamic threshold is used
* to detect defects. Finally, the results are displayed.
* 
* 
* tuning parameters
SmoothX := 501
ThresholdOffset := 25
MinDefectSize := 50
* 
* initialization
PolarResolution := 640
RingSize := 70
get_system ('store_empty_region', StoreEmptyRegion)
set_system ('store_empty_region', 'false')
read_image (Image, 'bottles/bottle_mouth_01')
dev_update_off ()
dev_close_window ()
dev_close_window ()
dev_open_window_fit_image (Image, 0, 0, 640, 512, WindowHandle1)
set_display_font (WindowHandle1, 16, 'mono', 'true', 'false')
dev_display (Image)
dev_set_draw ('margin')
dev_set_line_width (3)
dev_open_window_fit_size (0, 648, RingSize, PolarResolution, 150, 512, WindowHandle)
dev_set_draw ('margin')
dev_set_line_width (3)
dev_set_color ('red')
* 
* Main loop
* 
* Detect defects in bottle necks
for Index := 1 to 16 by 1
    read_image (Image, 'bottles/bottle_mouth_' + Index$'.02')
    * 
    * Part 1: Use basic morphology to detect bottle
    auto_threshold (Image, Regions, 2)
    select_obj (Regions, DarkRegion, 1)
    opening_circle (DarkRegion, RegionOpening, 3.5)
    closing_circle (RegionOpening, RegionClosing, 25.5)
    fill_up (RegionClosing, RegionFillUp)
    boundary (RegionFillUp, RegionBorder, 'outer')
    dilation_circle (RegionBorder, RegionDilation, 3.5)
    reduce_domain (Image, RegionDilation, ImageReduced)
    * 
    * Find the bottle center by fitting a circle to extracted edges
    edges_sub_pix (ImageReduced, Edges, 'canny', 0.5, 20, 40)
    segment_contours_xld (Edges, ContoursSplit, 'lines_circles', 5, 4, 2)
    union_cocircular_contours_xld (ContoursSplit, UnionContours, 0.9, 0.5, 0.5, 200, 50, 50, 'true', 1)
    length_xld (UnionContours, Length)
    select_obj (UnionContours, LongestContour, sort_index(Length)[|Length| - 1] + 1)
    fit_circle_contour_xld (LongestContour, 'ahuber', -1, 0, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)
    * 
    * Part 2: Transform the ring-shaped bottle neck region to a rectangle
    gen_circle (Circle, Row, Column, Radius)
    dilation_circle (Circle, RegionDilation, 5)
    erosion_circle (Circle, RegionErosion, RingSize - 5)
    difference (RegionDilation, RegionErosion, RegionDifference)
    reduce_domain (Image, RegionDifference, ImageReduced)
    polar_trans_image_ext (ImageReduced, ImagePolar, Row, Column, 0, rad(360), Radius - RingSize, Radius, PolarResolution, RingSize, 'nearest_neighbor')
    * 
    * Part 3: Find defects with a dynamic threshold
    * Note the strong smoothing in x-direction in the transformed image.
    scale_image_max (ImagePolar, ImageScaleMax)
    mean_image (ImageScaleMax, ImageMean, SmoothX, 3)
    dyn_threshold (ImageScaleMax, ImageMean, Regions1, 55, 'not_equal')
    connection (Regions1, Connection)
    select_shape (Connection, SelectedRegions, 'height', 'and', 9, 99999)
    * ignore noise regions
    closing_rectangle1 (SelectedRegions, RegionClosing1, 10, 20)
    union1 (RegionClosing1, RegionUnion)
    * re-transform defect regions for visualization
    polar_trans_region_inv (RegionUnion, XYTransRegion, Row, Column, 0, rad(360), Radius - RingSize, Radius, PolarResolution, RingSize, 1280, 1024, 'nearest_neighbor')
    * 
    * Part 4: Display results
    * display original image with results
    dev_set_window (WindowHandle1)
    dev_display (Image)
    dev_set_color ('blue')
    dev_display (RegionDifference)
    dev_set_color ('red')
    dev_display (XYTransRegion)
    * display polar transformed inspected region with results
    * The image and resulting region are rotated by 90 degrees
    * only for visualization purposes! (I.e. to fit better on the screen)
    * The rotation is NOT necessary for the detection algorithm.
    dev_set_window (WindowHandle)
    rotate_image (ImagePolar, ImageRotate, 90, 'constant')
    dev_display (ImageRotate)
    count_obj (RegionUnion, Number)
    if (Number > 0)
        mirror_region (RegionUnion, RegionMirror, 'diagonal', PolarResolution)
        mirror_region (RegionMirror, RegionMirror, 'row', PolarResolution)
        dev_display (RegionMirror)
        disp_message (WindowHandle1, 'Not OK', 'window', 12, 12, 'red', 'false')
    else
        disp_message (WindowHandle1, 'OK', 'window', 12, 12, 'forest green', 'false')
    endif
    if (Index < 16)
        disp_continue_message (WindowHandle1, 'black', 'true')
        stop ()
    endif
endfor
* Reset system parameters
set_system ('store_empty_region', StoreEmptyRegion)

在这里插入图片描述

Halcon Blob+局部二值化+特征提取缺陷检测

在这里插入图片描述

在这里插入图片描述

* The task of this example is to detect defects on a
* web using the operator dyn_threshold. In this way,
* the operator can be used to find textures that
* differ from the rest of the image.
*1.采集图像
dev_update_window ('off')
read_image (Image, 'plastic_mesh/plastic_mesh_01')
dev_close_window ()
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, Width, Height, WindowHandle)
set_display_font (WindowHandle, 18, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_set_line_width (3)
* Each of the images is read and smoothed. Subsequently
* dyn_threshold is performed and connected regions are
* looked for. The parameter 'area' of the operator select_shape
* makes it possible to find regions that differ in the area
* size. Found errors are finally counted and displayed.
for J := 1 to 14 by 1
    *2.图像分割(局部阈值法)
    read_image (Image, 'plastic_mesh/plastic_mesh_' + J$'02')
    mean_image (Image, ImageMean, 49, 49)
    dyn_threshold (Image, ImageMean, RegionDynThresh, 5, 'dark')
    *3.特征提取
    *形成不同的连通域
    connection (RegionDynThresh, ConnectedRegions)
    *选择面积特征如果面积特征大于500 则有缺陷
    select_shape (ConnectedRegions, ErrorRegions, 'area', 'and', 500, 99999)
    count_obj (ErrorRegions, NumErrors)
    dev_display (Image)
    dev_set_color ('red')
    dev_display (ErrorRegions)
    * If the number of errors exceeds zero, the message 'Mesh not
    * OK' is displayed. Otherwise the web is undamaged
    * and 'Mesh OK' is displayed.
    if (NumErrors > 0)
        disp_message (WindowHandle, 'Mesh not OK', 'window', 24, 12, 'black', 'true')
    else
        disp_message (WindowHandle, 'Mesh OK', 'window', 24, 12, 'black', 'true')
    endif
    * If the sequence number of the image to be inspected is
    * lower than 14, the request to press 'Run' to continue appears.
    * If the last image is read, pressing 'Run' will clear the SVM.
    if (J < 14)
        disp_continue_message (WindowHandle, 'black', 'true')
        stop ()
    endif
endfor

在这里插入图片描述

Halcon blob+灰度差分+特征缺陷检测案例

在这里插入图片描述

在这里插入图片描述

read_image (Image, 'pcb')
dev_close_window ()
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_display (Image)
* detect defects ...
* 灰度开运算暗点增多
gray_opening_shape (Image, ImageOpening, 7, 7, 'octagon')
* 灰度闭运算暗点增多
gray_closing_shape (Image, ImageClosing, 7, 7, 'octagon')
* 二值化亮暗点都提取出来,两个图像相减
dyn_threshold (ImageOpening, ImageClosing, RegionDynThresh, 75, 'not_equal')
dev_display (Image)
dev_set_color ('red')
dev_set_draw ('margin')
dev_display (RegionDynThresh)

在这里插入图片描述

Halcon 定位(blob求角度)+特征

思路:先读取图片,读取一个没有缺陷的图片,进行图片的仿射运算,获取每一个药片的位置,在读取一个可能有缺陷的图片,进行仿射运算,获取每一个药片的位置,之后进行相交,面积小于0(有缺陷),面积大于0判断灰度值的区间,在区间内有缺陷,在区间外没有缺陷
在这里插入图片描述

* This example demonstrates an application from the pharmaceutical
* industry. The task is to check the content of automatically filled
* blisters. The first image (reference) is used to locate the chambers
* within a blister shape as a reference model, which is then used to
* realign the subsequent images along to this reference shape. Using
* blob analysis the content of each chamber is segmented and finally
* classified by a few shape features.
* 1.采集图像
dev_close_window ()
dev_update_off ()
read_image (ImageOrig, 'blister/blister_reference')
dev_open_window_fit_image (ImageOrig, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_set_line_width (3)
* 
* In the first step, we create a pattern to cut out the chambers in the
* subsequent blister images easily.
* 2.定位求标准位置(blob分析)
*获取一个bgr通道
access_channel (ImageOrig, Image1, 1)
*二值化
threshold (Image1, Region, 90, 255)
*凸性转换
shape_trans (Region, Blister, 'convex')
*求区域角度
orientation_region (Blister, Phi)
*求区域的中心点行列坐标面积
area_center (Blister, Area1, Row, Column)
*形成仿射变换矩阵
vector_angle_to_rigid (Row, Column, Phi, Row, Column, 0, HomMat2D)
*对图像求仿射变换
affine_trans_image (ImageOrig, Image2, HomMat2D, 'constant', 'false')
*产生一个空的物体
gen_empty_obj (Chambers)
for I := 0 to 4 by 1
    *行
    Row := 88 + I * 70
    for J := 0 to 2 by 1
        *列
        Column := 163 + J * 150
        *形成一个空的矩形区域
        gen_rectangle2 (Rectangle, Row, Column, 0, 64, 30)
        *存储图像
        concat_obj (Chambers, Rectangle, Chambers)
    endfor
endfor
*对区域求仿射变换
affine_trans_region (Blister, Blister, HomMat2D, 'nearest_neighbor')
*区域求差(药板和药片求差) 药板-药片=药板的骨架部分
difference (Blister, Chambers, Pattern)
*将药片合并
union1 (Chambers, ChambersUnion)
*获取药板区域的角度
orientation_region (Blister, PhiRef)
PhiRef := rad(180) + PhiRef
*获取药板区域的面积,行列坐标
area_center (Blister, Area2, RowRef, ColumnRef)
* 
* 
* Each image read will be aligned to this pattern and reduced to the area of interest,
* which is the chambers of the blister
* 3.缺陷检测,在标准的位置抠药片和原来的区域数组求交集来判断
Count := 6
for Index := 1 to Count by 1
    read_image (Image, 'blister/blister_' + Index$'02')
    threshold (Image, Region, 90, 255)
    connection (Region, ConnectedRegions)
    select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 5000, 9999999)
    shape_trans (SelectedRegions, RegionTrans, 'convex')
    * 
    * Align pattern along blister of image
    * 仿射变换将位置摆正
    orientation_region (RegionTrans, Phi)
    area_center (RegionTrans, Area3, Row, Column)
    vector_angle_to_rigid (Row, Column, Phi, RowRef, ColumnRef, PhiRef, HomMat2D)
    affine_trans_image (Image, ImageAffineTrans, HomMat2D, 'constant', 'false')
    * 
    * Segment pills
    * 将仿射变换的区域和药片数组的区域裁剪出来
    reduce_domain (ImageAffineTrans, ChambersUnion, ImageReduced)
    * 获取三色通道
    decompose3 (ImageReduced, ImageR, ImageG, ImageB)
    * 均值和方差二值化
    var_threshold (ImageB, Region, 7, 7, 0.2, 2, 'dark')
    * 连接单个区域
    connection (Region, ConnectedRegions0)
    *闭运算
    closing_rectangle1 (ConnectedRegions0, ConnectedRegions, 3, 3)
    *填充
    fill_up (ConnectedRegions, RegionFillUp)
    *特征提取选择区域面积
    select_shape (RegionFillUp, SelectedRegions, 'area', 'and', 1000, 99999)
    *开运算
    opening_circle (SelectedRegions, RegionOpening, 4.5)
    * 将开运算的区域精选连接
    connection (RegionOpening, ConnectedRegions)
    *特征提取筛选出面积
    select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 1000, 99999)
    *将筛选出的特征的图像进行凸性处理
    shape_trans (SelectedRegions, Pills, 'convex')
    * 
    * Classify segmentation results and display statistics
    *获取药板中的药片数量
    count_obj (Chambers, Number)
    *产生一个药片缺陷的容器
    gen_empty_obj (WrongPill)
    *产生一个没有药片的容器
    gen_empty_obj (MissingPill)
    for I := 1 to Number by 1
        *选择标准药片
        select_obj (Chambers, Chamber, I)
        *标准药片和读取的药片求交集
        intersection (Chamber, Pills, Pill)
        *获取相交药片的行列坐标,面积
        area_center (Pill, Area, Row1, Column1)
        *如果面积大于0
        if (Area > 0)
            *求最大最小灰度值
            min_max_gray (Pill, ImageB, 0, Min, Max, Range)
            *如果灰度值小于3800大于60
            if (Area < 3800 or Min < 60)
                *错误的药片
                concat_obj (WrongPill, Pill, WrongPill)
            endif
        else
            *如果面积小于0 没有药片
            concat_obj (MissingPill, Chamber, MissingPill)
        endif
    endfor
    *  显示
    dev_clear_window ()
    dev_display (ImageAffineTrans)
    dev_set_color ('forest green')
    count_obj (Pills, NumberP)
    count_obj (WrongPill, NumberWP)
    count_obj (MissingPill, NumberMP)
    dev_display (Pills)
    if (NumberMP > 0 or NumberWP > 0)
        disp_message (WindowHandle, 'Not OK', 'window', 12, 12 + 600, 'red', 'true')
    else
        disp_message (WindowHandle, 'OK', 'window', 12, 12 + 600, 'forest green', 'true')
    endif
    * 
    Message := '# Correct pills: ' + (NumberP - NumberWP)
    Message[1] := '# Wrong pills  :  ' + NumberWP
    Message[2] := '# Missing pills:  ' + NumberMP
    * 
    Colors := gen_tuple_const(3,'black')
    if (NumberWP > 0)
        Colors[1] := 'red'
    endif
    if (NumberMP > 0)
        Colors[2] := 'red'
    endif
    disp_message (WindowHandle, Message, 'window', 12, 12, Colors, 'true')
    dev_set_color ('red')
    dev_display (WrongPill)
    dev_display (MissingPill)
    if (Index < Count)
        disp_continue_message (WindowHandle, 'black', 'true')
    endif
    stop ()
endfor

在这里插入图片描述

Halcon 定位(模板匹配)+测量

在这里插入图片描述

* In this example a fill level check for the
* pharmaceutical industry is demonstrated. The task is
* to check for the fill level of each single nose drop ampoule.
* To do so, we first locate each ampoule head by applying
* shape-based matching, then we find the fill level
* by measuring the gray level change using a 1D Measuring.
* 
* 1.采集图像
dev_close_window ()
dev_update_off ()
read_image (Image, 'ampoules/ampoules_01')
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
dev_set_line_width (2)
dev_set_draw ('margin')
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
* 2.定位找到参考线
* Create a model for the ampoule head to align the measure handle
*产生一个矩形
gen_rectangle1 (Rectangle, 230, 280, 317, 330)
* 矩形裁剪
reduce_domain (Image, Rectangle, ImageModel)
* 创建模板
create_shape_model (ImageModel, 'auto', 0, 0, 'auto', 'auto', 'use_polarity', 'auto', 'auto', ModelID)
* 
* Initialize the measure handle
* 初始化测量矩形
gen_measure_rectangle2 (0, 0, rad(90), 75, 20, Width, Height, 'bilinear', MeasureHandle)
Tolerance := 15
* 
* Determine the fill level
NumImages := 8
for Index := 1 to NumImages by 1
    * 读取图片
    read_image (Image, 'ampoules/ampoules_' + Index$'.2d')
    ColumnEdges := []
    FillLevelHeight := []
    * 查找模板
    find_shape_model (Image, ModelID, 0, 0, 0.7, 0, 0.1, 'least_squares', 0, 0.9, Row, Column, Angle, Score)
    * 平均行
    MeanRow := mean(Row)
    * 参考线 =平均水平坐标-160
    RefLevel := MeanRow - 160
    * Display tolerance area
    dev_display (Image)
    dev_set_line_width (1)
    dev_set_color ('white')
    * 产生一个参考矩形,参考矩形的中间的线为参考线
    gen_rectangle2 (AcceptLevel, RefLevel, mean(Column), 0, 30 + (max(Column) - min(Column)) / 2, Tolerance)
    * 绘制矩形
    dev_display (AcceptLevel)
    dev_set_line_width (2)
    *  3.形成测量矩形找液面边缘
    *  Determine fill level of each ampoule
    Errors := 0
    for Idx := 0 to |Score| - 1 by 1
        * 移动到测量点,行=参考的基准-135,列模板匹配到的列
        translate_measure (MeasureHandle, MeanRow - 135, Column[Idx])
        * Search for the topmost edge
        * 测量边
        measure_pos (Image, MeasureHandle, 2, 7, 'all', 'first', RowEdge, ColumnEdge, Amplitude, Distance)
        FillLevelHeight := [FillLevelHeight,RowEdge]
        ColumnEdges := [ColumnEdges,ColumnEdge]
        * 生成亚像素轮廓
        gen_cross_contour_xld (Cross, RowEdge, ColumnEdge, 15, 0)
        * 绘制矩形
        gen_rectangle2 (FillLevel, RowEdge, ColumnEdge, 0, 28, 20)
        * 4.计算参考线和边缘之间的距离
        * 判断是否合格,水平高度 - 矩形的高度 >= 15 不合格
        if (abs(FillLevelHeight[Idx] - RefLevel) >= Tolerance)
            * 产生一个矩形
            gen_rectangle2 (ChamberSingle, MeanRow - 133, Column[Idx], 0, 35, 90)
            * 产生十字
            gen_cross_contour_xld (Cross, FillLevelHeight[Idx], ColumnEdges[Idx], 15, 0)
            gen_rectangle2 (FillLevel, FillLevelHeight[Idx], ColumnEdges[Idx], 0, 28, 20)
            Errors := Errors + 1
            dev_set_color ('red')
            dev_display (ChamberSingle)
            disp_message (WindowHandle, 'NG', 'image', FillLevelHeight[Idx] - 50, ColumnEdges[Idx] - 10, 'red', 'false')
        else
            disp_message (WindowHandle, 'OK', 'image', FillLevelHeight[Idx] - 50, ColumnEdges[Idx] - 10, 'green', 'false')
            dev_set_color ('green')
        endif
        dev_display (FillLevel)
        dev_display (Cross)
    endfor
    * 
    * Check, whether the fill level is within the allowed range - does not deviate too much
    * from average fill level
    * 
    * Display statistics
    *显示
    if (Errors > 0)
        disp_message (WindowHandle, Errors + ' BAD', 'window', 10, 12, 'red', 'true')
    else
        disp_message (WindowHandle, 'All OK', 'window', 10, 12, 'forest green', 'true')
    endif
    if (Index < NumImages)
        disp_continue_message (WindowHandle, 'black', 'true')
        stop ()
    endif
endfor

在这里插入图片描述

Halcon 拟合方法的求缺陷

在这里插入图片描述

* This example program shows how fit_rectangle2_contour_xld can be used to
* detect manufacturing errors of punched holes in a metal part.  The errors
* show up as small protrusions of the metal into the hole.  They can be detected
* by fitting rectangles to the edges of the hole robustly (i.e., with outlier
* suppression) and the calculating the distances of the edges to the rectangle
* sides using dist_rectangle2_contour_points_xld.  Since the corners of the
* holes are slightly rounded, some extra processing must be performed to
* disregard the corners in the check for errors.
* 1.图像的采集
dev_update_off ()
read_image (Image, 'punched_holes')
get_image_size (Image, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_display (Image)
* Since the metal part is backlit, the processing speed can be increased
* significantly by constructing a ROI for the subpixel-precise edge extraction
* that is as small as possible.  This can easily be achieved by thresholding and
* morphology.
* 2.预处理(逼近边缘图像,进行抠图1.手画 2.blob分析)
fast_threshold (Image, Region, 128, 255, 10)
* 求区域内边界
boundary (Region, Border, 'inner')
* 矩形膨胀
dilation_rectangle1 (Border, EdgeROI, 7, 7)
* 抠图
reduce_domain (Image, EdgeROI, ImageReduced)
* Perform the edge extraction.
* 边缘亚像素处理
edges_sub_pix (ImageReduced, Edges, 'canny', 1.7, 40, 120)
* Remove edge fragments that are too short.
* 选择需要的区域周长 500以上
select_shape_xld (Edges, RectangleEdges, 'contlength', 'and', 500, 100000)
* Fit rectangles to the holes' edges using the outlier suppression of Tukey.
* 拟合最小外接矩形
fit_rectangle2_contour_xld (RectangleEdges, 'tukey', -1, 0, 0, 3, 2, Row, Column, Phi, Length1, Length2, PointOrder)
* Create rectangles with the fitted parameters for visualization purposes.
* 形成一个拟合的矩形区域
gen_rectangle2_contour_xld (Rectangles, Row, Column, Phi, Length1, Length2)
dev_set_color ('yellow')
dev_display (Rectangles)
* Check whether the holes are OK.
* 求轮廓上的点和最小外接矩形上的点之间的距离
count_obj (RectangleEdges, Number)
for I := 0 to Number - 1 by 1
    *选择获取轮廓
    select_obj (RectangleEdges, RectangleEdge, I + 1)
    * Get the contour's coordinates.
    * 获取亚像素轮廓上的点的坐标
    get_contour_xld (RectangleEdge, Rows, Cols)
    * Create a rectangle with the appropriate rectangle parameters.
    *产生一个亚像素轮廓矩形
    gen_rectangle2_contour_xld (Rect, Row[I], Column[I], Phi[I], Length1[I], Length2[I])
    * Get the coordinates of the rectangle's corners.
    *获取产生亚像素轮廓点的坐标 (获取坐标点的四个顶点,最后一个点回到原点,一共5个点)
    get_contour_xld (Rect, RowC, ColC)
    * Calculate the distances of all the contour points to the four corners of the
    * rectangle.
    * 勾股定理求两点之间的距离
    D1 := sqrt((Rows - RowC[0]) * (Rows - RowC[0]) + (Cols - ColC[0]) * (Cols - ColC[0]))
    D2 := sqrt((Rows - RowC[1]) * (Rows - RowC[1]) + (Cols - ColC[1]) * (Cols - ColC[1]))
    D3 := sqrt((Rows - RowC[2]) * (Rows - RowC[2]) + (Cols - ColC[2]) * (Cols - ColC[2]))
    D4 := sqrt((Rows - RowC[3]) * (Rows - RowC[3]) + (Cols - ColC[3]) * (Cols - ColC[3]))
    * The distance of the contour points to the corners of the rectangle is given
    * by the minimum of the four distances.  This distance is used to exclude
    * contour points that are too close to the corners from the check for errors.
    *点到轮廓的最小距离(点到四个顶点的距离)
    DistCorner := min2(min2(D1,D2),min2(D3,D4))
    * Calculate the distances of the contour points of the rectangle.
    * 求轮廓上的点到最小外接矩形边的距离
    dist_rectangle2_contour_points_xld (RectangleEdge, 0, Row[I], Column[I], Phi[I], Length1[I], Length2[I], Dist)
    * Check whether the hole is OK by examining the distances of the contour
    * points to the rectangle.  A hole is OK if all points that lie more than seven
    * pixels from the corners have a distance of less than one pixel to the fitted
    * rectangle.  To do so, we could use the following code:
*     RectangleOK := true
*     for J := 0 to |Dist| - 1 by 1
*         if (DistCorner[J] > 7.0 and Dist[J] > 1.0)
*             RectangleOK := false
*             break
*         endif
*     endfor
    * A much faster way to do this in HDevelop is to generate a mask that
    * contains 0 for all points that should not be taken into account and 1
    * otherwise.  To do so, we subtract the minimum distance of 7.0 from the
    * distances to the corners and take the maximum of 0.0 and the resulting
    * values.  This sets all the distances that are too close to the corners to 0.
    * To set all other values to 1, we can simply take the sign of the values.
    *去除矩形的四个角上的点
    *sgn为符号函数将DistCorner - 7.00的值设置为1 ,如果没有>0的就为0-7.0 为了排除拐角的距离
    Mask := sgn(max2(DistCorner - 7.0,0.0))
    * We can now multiply the distances to the rectangle with the mask and
    * check whether the maximum distance is smaller than the maximum allowed
    * distance of 1.0.
    * 如果max(Dist * Mask)<= 1.0则为正常,否则有缺陷
    RectangleOK := max(Dist * Mask) <= 1.0
    * Display whether the hole is OK.
    if (RectangleOK)
        dev_set_color ('green')
        get_string_extents (WindowHandle, 'OK', Ascent, Descent, Width, Height)
        set_tposition (WindowHandle, Row[I] - Height / 2, Column[I] - Width / 2)
        write_string (WindowHandle, 'OK')
    else
        dev_set_color ('red')
        get_string_extents (WindowHandle, 'Not OK', Ascent, Descent, Width, Height)
        set_tposition (WindowHandle, Row[I] - Height / 2, Column[I] - Width / 2)
        write_string (WindowHandle, 'Not OK')
    endif
endfor

在这里插入图片描述
在这里插入图片描述

Mask := sgn(max2(DistCorner - 7.0,0.0))排除拐角的距离
在这里插入图片描述

Halcon OCV光学字符检测

OCV 模板创建

在这里插入图片描述

* Saving an OCV tool to file
* 1.采集图像
read_image (Image, 'a01')
* 2.提取字符
threshold (Image, Region, 0, 100)
shape_trans (Region, RegionTrans, 'rectangle1')
dilation_rectangle1 (RegionTrans, RegionDilation, 10, 10)
* Reduce the domain of an image.
reduce_domain (Image, RegionDilation, ImageReduced)
* Create a new OCV tool based on gray value projections
* 3.训练
* 创建ocv模型
create_ocv_proj ('A', OCVHandle)
* 训练模型
traind_ocv_proj (ImageReduced, OCVHandle, 'A', 'single')
* 保存ocv文件
write_ocv (OCVHandle, 'test_ocv.ocv')
OCVHandle := []
stop ()
read_ocv ('test_ocv.ocv', OCVHandle)

在这里插入图片描述

OCV 字符质量缺陷识别

在这里插入图片描述

* 1.读取图像
read_image (Image, 'fonts/arial_a1')
get_image_size (Image, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width / 2, Height / 2 + 42, 'black', WindowHandle)
dev_set_part (-84, 0, Height - 1, Width - 1)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
dev_display (Image)
dev_set_draw ('margin')
gen_rectangle1 (Rectangle, 37, 69, 115, 141)
reduce_domain (Image, Rectangle, ImageReduced)
* 2.创建模板
create_ocv_proj ('A', OCVHandle)
* 训练
traind_ocv_proj (ImageReduced, OCVHandle, 'A', 'single')
dev_set_color ('red')
for I := 1 to 9 by 1
    read_image (Image, 'fonts/arial_a' + I)
    binary_threshold (Image, Region, 'max_separability', 'dark', UsedThreshold)
    connection (Region, ConnectedRegions)
    select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 150, 99999)
    sort_region (SelectedRegions, SortedRegions, 'character', 'true', 'row')
    select_obj (SortedRegions, ObjectSelected, 1)
    shape_trans (ObjectSelected, RegionTrans, 'rectangle1')
    dilation_rectangle1 (RegionTrans, RegionDilation, 15, 15)
    reduce_domain (Image, RegionDilation, ImageReduced)
    * Quality 获取字符质量
    do_ocv_simple (ImageReduced, OCVHandle, 'A', 'true', 'true', 'true', 'true', 5, Quality)
    * Display quality  质量大于0.9合格
    if (Quality > 0.9)
        Color := 'green'
    elseif (Quality > 0.7)
        Color := 'yellow'
    else
        Color := 'red'
    endif
    dev_display (Image)
    dev_set_color (Color)
    dev_set_line_width (2)
    dev_display (RegionDilation)
    disp_message (WindowHandle, 'Check print quality of \'A\' (Image  ' + I + ' of 9)', 'window', 12, 12, 'black', 'true')
    disp_message (WindowHandle, 'Quality = ' + Quality$'.2f', 'image', 120, 12, 'black', Color)
    if (I < 9)
        disp_continue_message (WindowHandle, 'black', 'true')
        stop ()
    endif
endfor

在这里插入图片描述

OCV 字符缺陷检测展示案例

在这里插入图片描述

read_image (Image, 'a01')
get_image_size (Image, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_display (Image)
threshold (Image, Region, 0, 100)
shape_trans (Region, RegionTrans, 'rectangle1')
dilation_rectangle1 (RegionTrans, RegionDilation, 10, 10)
reduce_domain (Image, RegionDilation, ImageReduced)
create_ocv_proj ('A', OCVHandle)
traind_ocv_proj (ImageReduced, OCVHandle, 'A', 'single')
dev_set_color ('red')
for add := -20 to 20 by 1
    scale_image (Image, ImageScaled, 1, add)
    reduce_domain (ImageScaled, RegionDilation, ImageReduced)
    do_ocv_simple (ImageReduced, OCVHandle, 'A', 'true', 'true', 'true', 'true', -1, Quality)
    set_tposition (WindowHandle, 24, 12)
    write_string (WindowHandle, 'Intensity change = ' + add + '       Quality = ' + Quality)
    stop ()
endfor
for scale := 0.8 to 1.2 by 0.025
    scale_image (Image, ImageScaled, scale, 0)
    reduce_domain (ImageScaled, RegionDilation, ImageReduced)
    do_ocv_simple (ImageReduced, OCVHandle, 'A', 'true', 'true', 'true', 'true', -1, Quality)
    set_tposition (WindowHandle, 24, 12)
    write_string (WindowHandle, 'Intensity scale = ' + scale + '       Quality = ' + Quality)
    stop ()
endfor
for Length := 1 to 17 by 1
    gen_rectangle1 (Rectangle, 150, 145, 150 + 5, 145 + Length)
    paint_region (Rectangle, Image, ImageError, 210, 'fill')
    reduce_domain (ImageError, RegionDilation, ImageReduced)
    do_ocv_simple (ImageReduced, OCVHandle, 'A', 'true', 'true', 'true', 'true', -1, Quality)
    set_tposition (WindowHandle, 24, 12)
    write_string (WindowHandle, 'Length of rectangle = ' + Length + '   Quality = ' + Quality)
    stop ()
endfor

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1435148.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PySpark(四)PySpark SQL、Catalyst优化器、Spark SQL的执行流程

目录 PySpark SQL 基础 SparkSession对象 DataFrame入门 DataFrame构建 DataFrame代码风格 DSL SQL SparkSQL Shuffle 分区数目 DataFrame数据写出 Spark UDF Catalyst优化器 Spark SQL的执行流程 PySpark SQL 基础 PySpark SQL与Hive的异同 Hive和Spark 均是:“分…

2月5日作业

1.请编程实现哈希表的创建存储数组(12,24,234,234,23,234,23),输入key查找的值&#xff0c;实现查找功能 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<math.h> typedef int datatype; typedef struct node {datatype data;str…

JenkinsGitLab完成自动化构建部署

关于GitLab安装:GitLab安装-CSDN博客 Docker中安装GitLab:Docker下安装GitLab-CSDN博客 安装JenKins Jenkins官网:Jenkins 中文版:Jenkins 安装时候中文页面的war包下不来 在英文页面 记得装JDK8以上 JenKins使用java写的 运行JenKins需要JDK环境 我这里已经装好了 将下…

VXLAN:虚拟化网络的强大引擎

1.什么是VXLAN VXLAN&#xff08;Virtual eXtensible Local Area Network&#xff0c;虚拟扩展局域网&#xff09;&#xff0c;是由IETF定义的NVO3&#xff08;Network Virtualization over Layer 3&#xff09;标准技术之一&#xff0c;是对传统VLAN协议的一种扩展。VXLAN的特…

华为云GaussDB在新零售云转型上的摸索实验

新零售的“云化” 阿里研究院曾经提到过一个理念&#xff1a; 零售的本质是无时无刻不为消费者提供超出预期的“内容”。 这个理念其实不难理解&#xff0c;想要留住消费者&#xff0c;靠大家都能提供的“内容”显然是行不通的。超出预期&#xff0c;才能吸引消费者的“消费…

5-4、S加减单片机程序【51单片机+L298N步进电机系列教程】

↑↑↑点击上方【目录】&#xff0c;查看本系列全部文章 摘要&#xff1a;本节介绍实现步进电机S曲线运动的代码 一、目标功能 实现步进电机转动总角度720&#xff0c;其中加减速各90 加速段&#xff1a;加速类型&#xff1a;S曲线  加速角度&#xff1a;角度为90  起步速度…

Python:批量url链接保存为PDF

我的数据是先把url链接获取到存入excel中&#xff0c;后续对excel做的处理&#xff0c;各位也可以直接在程序中做处理&#xff0c;下面就是针对excel中的链接做批量处理 excel内容格式如下&#xff08;涉及具体数据做了隐藏&#xff09; 标题文件链接文件日期网页标题1http://…

标准库 STM32+EC11编码器+I2C ssd1306多级菜单例程

标准库 STM32EC11编码器I2C ssd1306多级菜单例程 &#x1f4cc;原创项目来源于&#xff1a;https://github.com/AdamLoong/Embedded_Menu_Simple&#x1f4cd;相关功能演示观看&#xff1a;https://space.bilibili.com/74495335 单片机多级菜单v1.2 &#x1f449;本次采用的是原…

对于模糊查询的SQL,怎么优先返回等值记录

说明&#xff1a;记录一次SQL改进的方法&#xff0c;希望能对大家有启发。 场景 前端项目有一个输入框&#xff0c;根据输入的银行名称&#xff0c;去模糊查询对应的数据库表&#xff0c;返回结果集&#xff0c;显示到下拉列表中。 因为银行名称字段包括了分行名&#xff0c…

【机器学习】机器学习简单入门

&#x1f388;个人主页&#xff1a;甜美的江 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;matplotlib &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

Linux基础-磁盘

1.磁盘分区 1.分区有固定大小 2.直接写在这块盘的磁盘分区表中&#xff08;DPT&#xff09;&#xff0c;和上面装什么操作系统没有任何关系 2.每一个磁盘分区都要先有一个磁盘分区类型 GPT&#xff08;首选&#xff09; MBR 3.磁盘专业术语叫做块设备&#xff08;Block Dev…

re:从0开始的CSS学习之路 2. 选择器超长大合集

0. 写在前面 虽然现在还是不到25的青年人&#xff0c;有时仍会感到恐慌&#xff0c;害怕不定的未来&#xff0c;后悔失去的时间&#xff0c;但细细想来&#xff0c;只有自己才知道&#xff0c;再来一次也不会有太多的改变。 CSS的选择器五花八门&#xff0c;而且以后在JavaScr…

【DDD】学习笔记-数据模型与对象模型

在建立数据设计模型时&#xff0c;我们需要注意表设计与类设计之间的差别&#xff0c;这事实上是数据模型与对象模型之间的差别。 数据模型与对象模型 我们首先来分析在设计时对冗余的考虑。前面在讲解数据分析模型时就提及&#xff0c;在确定数据项模型时&#xff0c;需要遵…

Go语言每日一练——链表篇(五)

传送门 牛客面试笔试必刷101题 ----------------合并k个已排序的链表 题目以及解析 题目 解题代码及解析 解析 这一道题与昨天的合并链表题目类似&#xff0c;但是由于有K个且时间复杂度要求控制在O(nlogn)&#xff0c;这里主要有两种解法&#xff1a;一种是依旧使用归并来…

7.0 Zookeeper 客户端基础命令使用

zookeeper 命令用于在 zookeeper 服务上执行操作。 首先执行命令&#xff0c;打开新的 session 会话&#xff0c;进入终端。 $ sh zkCli.sh 下面开始讲解基本常用命令使用&#xff0c;其中 acl 权限内容在后面章节详细阐述。 ls 命令 ls 命令用于查看某个路径下目录列表。…

函数的连续与间断【高数笔记】

【连续】 分类&#xff0c;分几个&#xff1f;每类特点&#xff1f; 连续条件&#xff0c;是同时满足还是只需其一&#xff1f; 【间断】 分类&#xff0c;分几个大类&#xff0c;又分几个小类&#xff1f;每类特点&#xff1f; 间断条件&#xff0c;是同时满足还是只需其一&am…

PAT-Apat甲级题1008(python和c++实现)

PTA | 1008 Elevator 1008 Elevator 作者 CHEN, Yue 单位 浙江大学 The highest building in our city has only one elevator. A request list is made up with N positive numbers. The numbers denote at which floors the elevator will stop, in specified order. It …

【C/C++ 17】继承

目录 一、继承的概念 二、基类和派生类对象赋值转换 三、继承的作用域 四、派生类的默认成员函数 五、继承与友元 六、继承与静态成员变量 七、菱形继承与虚拟继承 一、继承的概念 继承是指一个类可以通过继承获得另一个类的属性和方法&#xff0c;扩展自己的功能&…

二、SSM 整合配置实战

本章概要 依赖整合和添加控制层配置编写(SpringMVC 整合)业务配置编写(AOP/TX 整合)持久层配置编写(MyBatis 整合)容器初始化配置类整合测试 2.1 依赖整合和添加 数据库准备 数据库脚本 CREATE DATABASE mybatis-example;USE mybatis-example;CREATE TABLE t_emp(emp_id INT…

MQ,RabbitMQ,SpringAMQP的原理与实操

MQ 同步通信 异步通信 事件驱动优势&#xff1a; 服务解耦 性能提升&#xff0c;吞吐量提高 服务没有强依赖&#xff0c;不担心级联失败问题 流量消峰 ​ 小结: 大多情况对时效性要求较高&#xff0c;所有大多数时间用同步。而如果不需要对方的结果&#xff0c;且吞吐…