程序员求职经验分享与学习资料整理平台

网站首页 > 文章精选 正文

HALCON_极坐标变换

balukai 2025-01-01 17:58:23 文章精选 8 ℃

图像预处理

动态阈值 mean_image 局部动态阈值 处理 普通二值化难以区分的场景

但是这种 水表盘却不能,使用 均值滤波和动态阈值

取不到图像


使用 VAR阈值

*与动态阈值类型,通过掩网

**参数 8, 8 掩膜宽度和高度, 0.2 标准差表, 4 绝对阈值, 'dark'亮暗

var_threshold (Image1, Region, 10, 10, 0.2, 6, 'dark')




接下来取轮廓

如果使用 edges_sub_pix 算子,由于上面的图像非常的细碎

所以用这种

*将刻度区域的region变成contour

** 转换区域到XLD轮廓

gen_contour_region_xld (SelectedRegions, Contours, 'border')

这个极坐标变换的 起始和终点角度

这个极坐标变换的 起始和终点角度

红色是水平线,红色的点是极坐标变换的圆心坐标

这个绿色的夹角,就是极坐标变换的起始和终点角度。

如果这两个角度不到位,是不能将仪表盘变换完整的





    count_seconds (S1)
    *读取图像转换颜色通道,然后阈值化选取最大联通区域
    read_image (Image1, '15.bmp')
    get_image_size(Image1, Width, Height)
    rgb3_to_gray (Image1, Image1, Image1, Image1)
    
   * mean_image (Image1, ImageMean, 10, 10)
   * dyn_threshold (ImageMean, ImageMean, RegionDynThresh, 100, 'light')
    
    
    *与动态阈值类型,通过掩网
    **参数  8, 8 掩膜宽度和高度, 0.2 标准差表, 4 绝对阈值, 'dark'亮暗
    var_threshold (Image1, Region4, 10, 10, 0.2, 6, 'dark')
    *var_threshold (Image1, Region4, 8, 8, 0.2, 4, 'dark')
    connection (Region4, ConnectedRegions)
    
   select_shape_std (ConnectedRegions, SelectedRegions, 'max_area', 70)
    
   reduce_domain (Image1, SelectedRegions, ImageReduced)
   *edges_sub_pix (ImageReduced, Edges, 'canny', 0.5, 20, 40)
   
    *将刻度区域的region变成contour
    ** 转换区域到XLD轮廓
    gen_contour_region_xld (SelectedRegions, Contours, 'border') 
    *采用这个方式进行分割 'lines_ellipses'
    segment_contours_xld (Contours, ContoursSplit, 'lines_ellipses', 3, 3.5, 2)
    *选取contour中的面积大部分,即上面的圆弧
    select_shape_xld (ContoursSplit, SelectedCircleXLD, 'area', 'and', 60000, 9999999)
    
    ** 通过拟合的方式找到 圆心 半径,内外圆, 方便后面的极坐标变换
    *圆弧拟合出一个圆
    fit_circle_contour_xld (SelectedCircleXLD, 'algebraic', \
                            -1, 0, 0, 3, 2, Row, Column, Radius, \
                            StartPhi, EndPhi, PointOrder)
    Row:= mean(Row)
    Column:=mean(Column)
    Radius:=mean(Radius)
    *各种取平均值后,画出圆心点便于观察
    gen_circle (Circle, Row, Column, 10)
    **创建圆弧XLD轮廓
    gen_circle_contour_xld(ContCircle,Row, Column, Radius,\
                           0, 6.28318, 'positive', 1)
    dev_set_draw ('fill')
    aa:=rad(360)
    bb:=rad(-120)
    *极坐标变化后继续阈值与选取最大区域,即刻度
*     polar_trans_image_ext (Image1,ImageTest, Row, Column,rad(240) ,rad(-120) , Radius+300, Radius-90, Radius*3.14, 500, 'bilinear')
    polar_trans_image_ext (Image1,ImageTest, Row, \
                           Column,rad(240) ,rad(-60) , \
                           Radius+300, Radius-90, Radius*3.14,\
                           500, 'bilinear')
    
    
    var_threshold (ImageTest, Region5, 10, 10, 0.2, 2, 'dark')
    connection (Region5, ConnectedRegions4)
    select_shape_std (ConnectedRegions4, SelectedRegions1, 'max_area', 70)
    *转换区域到XLD轮廓
    gen_contour_region_xld (SelectedRegions1, ContoursPolarAfter, 'center')
    *@继续分割contour然后选取刻度中上面的直线
    segment_contours_xld (ContoursPolarAfter, ContoursSplitPolarAfter,\
    'lines_circles', 5, 5, 4)
    ** 将刻度盘的基准线提取出来
    select_contours_xld (ContoursSplitPolarAfter, ContoursSplitPolarAfter1,\
                     'contour_length', 400, 9999, -0.5, 0.5)
    *将上面的直线膨胀,用difference将刻度中的小直线保留
    **转换XLD轮廓到区域
    gen_region_contour_xld (ContoursSplitPolarAfter1, RegionScalePolarAfter, 'margin')
    dilation_circle (RegionScalePolarAfter, RegionDilationScalePolar,5)
    
    difference (SelectedRegions1, RegionDilationScalePolar, RegionDifferencePolar)
    connection (RegionDifferencePolar, ConnectedScalePolar4)
    *排序全部刻度
    sort_region (ConnectedScalePolar4, SortedRegionsScalePolar,\
                 'character', 'true', 'row')
    *最小外接矩形
    smallest_rectangle1 (RegionDilationScalePolar, Row12, Column12, Row21, Column21)
    dev_set_draw('margin')
    dev_set_color('green')
    gen_rectangle1(rectang1,Row12, Column12, Row21, Column21)
    
    get_image_size (ImageTest, Width1, Height1)
    
    *** 往刻度盘下放一点点,画矩形,这个仪表盘的指针就在这个位置
    *得到极坐标变换后的图片的长宽
    *继续生成图像下部的小矩形(此处矩形的宽度是上面选的,需注意),然后可以
    dev_set_line_width(3)
    gen_rectangle1 (Rectangle3, Height1-10, min(Column12), Height1, max(Column21))
    
    gen_cross_contour_xld(Cross1, Height1-10, min(Column12), 6, 0.785398)
    gen_cross_contour_xld(Cross1,Height1, max(Column21), 6, 0.785398)
    
    
    *感兴趣区域提取  roi
    reduce_domain (ImageTest, Rectangle3, ImageReduced_rec1)
    *均值滤波
    mean_image (ImageReduced_rec1, ImageMean1, 5, 1)
    *动态二值化
    dyn_threshold (ImageReduced_rec1, ImageMean1, RegionDynThresh1, 5, 'dark')
    connection (RegionDynThresh1, ConnectedRegions7)
    *上面选择出来指针位置,下面用ra特征提取指针,需要保证图像大小,以及指针在里面所占像素大小
    **参数 ra 等效椭圆长轴半径长度
    select_shape (ConnectedRegions7, Region2_rec1, 'ra', 'and', 4 ,  8)

    
    smallest_rectangle2 (Region2_rec1, Row1_rec1, Column1_rec1, Phi1_rec1, Length11_rec1, Length21_rec1)
      *显示坐标的位置
    dev_set_color('blue')
    gen_cross_contour_xld(Cross, Row1_rec1, Column1_rec1, 16, Phi1_rec1)
    dev_set_color('yellow')
    
    *与上面矩形 角度 位置都相同,仅仅长度放大40倍
    gen_rectangle2 (Rectangle_line_rec1, Row1_rec1, \
                    Column1_rec1, Phi1_rec1, Length11_rec1*40, Length21_rec1)
    count_obj (SortedRegionsScalePolar, ScaleNumbersPolar)
    *    * re-transform defect regions for visualization
*     polar_trans_image_ext (Image1,ImageTest, Row, Column,rad(240) ,rad(-120) , Radius+300, Radius-90, Radius*3.14, 500, 'bilinear')
    *仿射回去进行显示
    polar_trans_region_inv (Region2_rec1, XYTransRegion, \
                            Row, Column,rad(240) ,rad(-120) ,\
                            Radius+300, Radius-90,  Radius*3.14,\
                            500, Width, Height, 'nearest_neighbor')
    
    polar_trans_region_inv (Rectangle_line_rec1, XYTrans_line_Region, \
                            Row, Column,rad(240) ,rad(-120) ,  \
                            Radius+300, Radius-90,  Radius*3.14,\
                            500, Width, Height, 'nearest_neighbor')
    *显示指针的位置
    dev_clear_window()
    dev_set_color('red')
    dev_display(Image1)
    dev_display(XYTransRegion)
    dev_display(XYTrans_line_Region)
    stop()
    
    dev_clear_window()
    dev_set_color('red')
    dev_display(ImageTest)
    dev_display(ImageReduced_rec1)
    dev_display(Region2_rec1)
   
    
  
    
    
    dev_clear_window()
    dev_set_color('red')
    dev_display(ImageTest)
    dev_set_color('green')
    dev_display(SortedRegionsScalePolar)
    count_obj(SortedRegionsScalePolar,NumberScalePolar)
    
    *计数可知道 总数为201 201/2 为101
    *这个是刻度的位置信息
    area_center (SortedRegionsScalePolar, SortedRegionsScalePolarArea, \
                 SortedRegionsScalePolarRow, SortedRegionsScalePolarColumn)
    count_seconds (S2)
    *计算一下时间
    tt := S2-S1
    *开始计算指针所在位置。  判断指针在左半边还是右半边。Column1_rec1为1742   所以在右半边
    *中间值  1448.81
    middle:=SortedRegionsScalePolarColumn[101]
    if (max(Column1_rec1) < SortedRegionsScalePolarColumn[101])
        for i := 0 to (ScaleNumbersPolar+1)/2 by 1
        if(max(Column1_rec1) < SortedRegionsScalePolarColumn[i])
            sigma:=(SortedRegionsScalePolarColumn[i]-max(Column1_rec1))/(SortedRegionsScalePolarColumn[i]-SortedRegionsScalePolarColumn[i-1])
             t:= 100-i+sigma
            break
        endif
        endfor
        stop()
        
    * 找指针的位置 。
    elseif(max(Column1_rec1) > SortedRegionsScalePolarColumn[101])
        
        *开始计算  从100开始计算到201 
        for i := 99 to ScaleNumbersPolar by 1
            
            *当这个数据小于SortedRegionsScalePolarColumn[i],停止,计算结果并跳出循环
            if(max(Column1_rec1) < SortedRegionsScalePolarColumn[i])
                stop()
             *再计算下 指针与(向上一级刻度)的距离   占整个小刻度的   比值。
            sigma:=(SortedRegionsScalePolarColumn[i]-max(Column1_rec1))/(SortedRegionsScalePolarColumn[i]-SortedRegionsScalePolarColumn[i-1])
            *这个t值就是指针的读数
            t:= i-100-sigma
            break
        endif
        endfor
        
    endif
    stop()
    dev_clear_window()
    dev_set_color('red')
    dev_display(Image1)
    dev_display(XYTransRegion)
    dev_display(XYTrans_line_Region)
    write_string (3600, '指针在  '+i+ ' 与'+i+1+'之间,读数为'+t+'运行时间' +tt+ ' V2') 
    stop()
    dev_clear_window ()


最近发表
标签列表