楼上有佬用空间域频域互转的方式去实现,这里我就用纯形态学和几何辅助的方式去抓边,代码如下:
- read_image (Image, './锯片.png')
- *//预处理
- set_system ('clip_region', 'false')
- get_image_size (Image, Width, Height)
- decompose3 (Image, R, G, B)
- trans_from_rgb (R, G, B, H, null, null, 'hsv')
- *//获得有效区域
- threshold (H, RegionB, 0, 60)
- connection (RegionB, RegionB)
- select_shape_std (RegionB, RegionB, 'max_area', 70)
- fill_up_shape (RegionB, RegionB, 'area', 1, 500)
- fill_up (RegionB, RegionBF)
- difference (RegionBF, RegionB, RegionInHole)
- smallest_circle (RegionInHole, Row, Column, Radius)
- gen_circle (RegionInHole, Row, Column, Radius)
- difference (RegionB, RegionInHole, RegionB)
- opening_circle (RegionBF, RegionBF, 3.5)
- *//预处理
- scale_image (H, H, 1.5, 0)
- mean_image (H, ImageD, 3, 3)
- *//动态阈值分割
- mean_image (ImageD, ImageDM, 25, 25)
- dyn_threshold (ImageD, ImageDM, RegionD, 1, 'light')
- intersection (RegionD, RegionB, RegionD)
- opening_circle (RegionD, RegionD, 1.5)
- connection (RegionD, RegionD)
- select_shape (RegionD, RegionD, 'area', 'and', 50, 9999999)
- union1 (RegionD, RegionD)
- *//补偿区域
- ang:=30
- gen_rectangle2 (RectSEHor, Height/2, Width/2, rad(ang), 3, 0.75)
- closing (RegionD, RectSEHor, RegionD1)
- gen_rectangle2 (RectSEVer, Height/2, Width/2, rad(90+ang), 5, 0.75)
- closing (RegionD1, RectSEVer, RegionD2)
- *//获得有效洞口区域
- fill_up (RegionD2, RegionD2F)
- difference (RegionD2F, RegionD2, RegionHole)
- connection (RegionHole, RegionHole)
- select_shape (RegionHole, RegionHole, ['area','rectangularity'], 'and', [260,0.6], [1500,1])
- closing_circle (RegionHole, RegionHole, 5.5)
- opening_circle (RegionHole, RegionHole, 3.5)
- select_shape (RegionHole, RegionHole, ['rect2_len1','rect2_len2'], 'and', [0,0], [10.5,10.5])
- union1 (RegionHole, RegionHole)
- *//横向处理
- *网格间距
- BTDisMin:=22
- BTDisMax:=30
- *//获得横向连接区域
- gen_rectangle2 (RectSEHor, Height/2, Width/2, rad(ang), 20, 0.5)
- closing (RegionHole, RectSEHor, RegionHoleH)
- connection (RegionHoleH, RegionHoleH)
- *//排序每列只取最左侧区域
- area_center (RegionHoleH, Area, RowHoleH, ColHoleH)
- select_shape_std (RegionHoleH, RegionHoleHM, 'max_area', 70)
- smallest_rectangle2 (RegionHoleHM, Row1, Col1, Phi, L1, L2)
- hom_mat2d_identity (HomMat2DI)
- hom_mat2d_rotate (HomMat2DI, -Phi, Row1, Col1, HomMat2DR)
- affine_trans_pixel (HomMat2DR, RowHoleH, ColHoleH, RowHoleHAF, ColHoleHAF)
- tuple_sort_index (RowHoleHAF, SortIdx)
- tuple_sort (RowHoleHAF, RowHoleHAF)
- *//计算行间距
- tuple_select (RowHoleHAF, [0:|RowHoleHAF|-2], RowHoleHAF1)
- tuple_select (RowHoleHAF, [1:|RowHoleHAF|-1], RowHoleHAF2)
- HDiff:=RowHoleHAF2-RowHoleHAF1
- if(HDiff[|HDiff|-1]>BTDisMax)
- else
- HDiff[|HDiff|]:=(BTDisMin+BTDisMax)/2
- endif
- tuple_select_by_range (HDiff, BTDisMin, BTDisMax, Idx)
- tuple_select (SortIdx, Idx, SortIdxS)
- *//得到筛选后的区域
- select_obj (RegionHoleH, RegionHoleH, SortIdxS+1)
- *//计算每一列的间距位
- smallest_rectangle2 (RegionHoleH, RowH, ColH, PhiH, L1H, L2H)
- tuple_gen_const (|RowH|, Phi, PhiH)
- gen_rectangle2 (RectH, RowH, ColH, PhiH, L1H+9999, L2H)
- union1 (RectH, RectH)
- difference (RegionBF, RectH, RectH)
- connection (RectH, RectH)
- sort_region (RectH, RectH, 'first_point', 'true', 'row')
- count_obj (RectH, Number)
- select_obj (RectH, RectH, [2:Number-1])
- difference (RectH, RegionInHole, RectH)
- skeleton (RectH, RectH)
- *//纵向处理
- *//获得纵向连接区域
- gen_rectangle2 (RectSEVer, Height/2, Width/2, rad(90+ang), 20, 0.5)
- closing (RegionHole, RectSEVer, RegionHoleV)
- connection (RegionHoleV, RegionHoleV)
- *//排序每行只取最左侧区域
- area_center (RegionHoleV, Area, RowHoleV, ColHoleV)
- select_shape_std (RegionHoleV, RegionHoleVM, 'max_area', 70)
- smallest_rectangle2 (RegionHoleVM, Row1, Col1, Phi, L1, L2)
- hom_mat2d_identity (HomMat2DI)
- hom_mat2d_rotate (HomMat2DI, -Phi, Row1, Col1, HomMat2DR)
- affine_trans_pixel (HomMat2DR, RowHoleV, ColHoleV, RowHoleVAF, ColHoleVAF)
- tuple_sort_index (RowHoleVAF, SortIdx)
- tuple_sort (RowHoleVAF, RowHoleVAF)
- *//计算行间距
- tuple_select (RowHoleVAF, [0:|RowHoleVAF|-2], RowHoleVAF1)
- tuple_select (RowHoleVAF, [1:|RowHoleVAF|-1], RowHoleVAF2)
- HDiff:=RowHoleVAF2-RowHoleVAF1
- if(HDiff[|HDiff|-1]>BTDisMax)
- else
- HDiff[|HDiff|]:=(BTDisMin+BTDisMax)/2
- endif
- tuple_select_by_range (HDiff, BTDisMin, BTDisMax, Idx)
- tuple_select (SortIdx, Idx, SortIdxS)
- *//得到筛选后的区域
- select_obj (RegionHoleV, RegionHoleV, SortIdxS+1)
- *//计算每一行的间距位
- smallest_rectangle2 (RegionHoleV, RowV, ColV, PhiV, L1V, L2V)
- tuple_gen_const (|RowV|, Phi, PhiV)
- gen_rectangle2 (RectV, RowV, ColV, PhiV, L1V+9999, L2V)
- union1 (RectV, RectV)
- difference (RegionBF, RectV, RectV)
- connection (RectV, RectV)
- sort_region (RectV, RectV, 'first_point', 'true', 'column')
- count_obj (RectV, Number)
- select_obj (RectV, RectV, [2:Number-1])
- difference (RectV, RegionInHole, RectV)
- skeleton (RectV, RectV)
- dev_clear_window ()
- dev_display (Image)
- dev_display (RectH)
- dev_display (RectV)
复制代码
|