图片资源
链接:https://pan.baidu.com/s/1Sh6e4VZybIVdNm3T9rgSrQ
提取码:inr2
处理流程
1、二值化连通域获取产品 初步位置
2、均值局部二值化 获取外框连通域
3、膨胀收缩 获取内部矩形区域
4、获取X轴线、获取Y轴线
5、检测大小灰尘处理
6、过滤边缘与杂质
完整代码
*****1、加载显示图片 ******************
dev_close_window ()
read_image (Image, './particle02.jpg')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_display (Image)
*****2、二值化连通域获取产品 初步位置 ******************
* 二值化 黑色区域
threshold (Image, Region, 0, 110)
fill_up (Region, RegionFillUp)
* 连通域分析
connection (RegionFillUp, ConnectedRegions)
* 连通域筛选 长宽筛选
select_shape (ConnectedRegions, SelectedRegions, 'rect2_len1', 'and', 200, 99999)
select_shape (SelectedRegions, SelectedRegions, 'rect2_len2', 'and', 200, 99999)
* 检查是否找到外框
count_obj (SelectedRegions, Number)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
if(Number # 1)
dev_disp_text ('未找到产品', 'window', 12, 12, 'black', 'box_color', '#fce9d4dd')
stop ()
endif
*****3、均值局部二值化 获取外框连通域 ******************
* 圆形收缩
erosion_circle (SelectedRegions, RegionErosion, 18)
* 定位到需要处理的区域
reduce_domain (Image, RegionErosion, ImageReduced)
* 均值处理
mean_image (ImageReduced, ImageMean, 60, 60)
* 动态阈值寻找边缘
dyn_threshold (ImageReduced, ImageMean, RegionDynThresh, 5, 'light')
* 连通域分析
connection (RegionDynThresh, ConnectedRegionsDyn)
* 面积筛选
select_shape (ConnectedRegionsDyn, selectedRegionsDyn, 'area', 'and', 15000, 999999)
* 检查是否找内框
count_obj (selectedRegionsDyn, NumberDyn)
if(NumberDyn # 1)
dev_disp_text ('未找到产品', 'window', 12, 12, 'black', 'box_color', '#fce9d4dd')
stop ()
endif
dev_display (Image)
dev_display (selectedRegionsDyn)
*****4、膨胀收缩 获取内部矩形区域 ******************
* 膨胀处理
dilation_rectangle1 (selectedRegionsDyn, RegionDilationDyn, 60, 60)
* 连通域联合
union1 (RegionDilationDyn, RegionUnionDyn)
* 连通域分析
connection (RegionUnionDyn, ConnectedRegionsDyn)
* 矩形腐蚀
erosion_rectangle1 (ConnectedRegionsDyn, RegionErosionDyn, 60, 60)
* 获取凸包区域
shape_trans (RegionErosionDyn, RegionTrans, 'convex')
* 减法获取内框矩形 (RegionTrans外部凸包区域,RegionErosionDyn内部矩形框)
difference (RegionTrans, RegionErosionDyn, RegionDifferenceT)
* 开运算去除多余部分 RegionOpeningT(内框连通域区域)
opening_rectangle1 (RegionDifferenceT, RegionOpeningT, 60, 60)
* 连通域分析
connection (RegionOpeningT, ConnectedRegionsT)
* 面积筛选
select_shape (ConnectedRegionsT, SelectedRegionsT, 'area', 'and', 15000, 9999009)
count_obj (SelectedRegionsT, NumberT)
if(NumberT # 1)
dev_disp_text ('未找到产品', 'window', 12, 12, 'black', 'box_color', '#fce9d4dd')
stop ()
endif
dev_display (Image)
dev_display (SelectedRegionsT)
*****4、获取X轴线 ******************
* 获取凸包区域
shape_trans (SelectedRegionsT, RegionTransT, 'convex')
* 内接矩形
boundary (RegionTransT, RegionBorderT, 'inner')
* 矩形腐蚀
erosion_rectangle1 (SelectedRegionsT, RegionErosionTest, 8, 8)
* 移动区域 row 方向移动10个像素
move_region (RegionErosionTest, RegionMoved, 10, 0)
* 交集处理 (下移动矩形(腐蚀缩小的) 与 内接矩形框(只有外框)的交集 )
* 下半线
intersection (RegionMoved, RegionBorderT, RegionIntersectionX)
* 骨骼处理 (直线的骨骼)
skeleton (RegionIntersectionX, SkeletonX)
* 绘制骨骼
gen_contours_skeleton_xld (SkeletonX, ContoursX, 1, 'filter')
* 直线平滑处理
smooth_contours_xld (ContoursX, SmoothedContoursX, 151)
* 轮廓分割成直线
segment_contours_xld (SmoothedContoursX, ContoursSplitX, 'lines', 5, 4, 2)
* 线性回归去除 干扰点
regress_contours_xld (ContoursSplitX, RegressContoursX, 'no', 1)
* 合并直线
union_straight_contours_xld (RegressContoursX, UnionContoursX, 500, 0.5, 50, 'noparallel', 'maximum')
* 拟合直线
fit_line_contour_xld (UnionContoursX, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
* 绘制直线
gen_region_line (RegionLinesX, RowBegin, ColBegin, RowEnd, ColEnd)
* 判断X直线是否存在
count_obj (UnionContoursX, NumberX)
if(NumberX # 1)
dev_disp_text ('未找到下边缘', 'window', 12, 12, 'black', 'box_color', '#fce9d4dd')
stop ()
endif
if(ColBegin > ColEnd)
gen_arrow_contour_xld (ArrowX, RowEnd, ColEnd, RowBegin, ColBegin, 50, 50)
else
gen_arrow_contour_xld (ArrowX, RowBegin, ColBegin, RowEnd, ColEnd, 50, 50)
endif
*****5、获取Y轴线(与x轴一样) ******************
move_region (RegionErosionTest, RegionMovedY, 0, -10)
intersection (RegionMovedY, RegionBorderT, RegionIntersectionY)
skeleton (RegionIntersectionY, SkeletonY)
gen_contours_skeleton_xld (SkeletonY, ContoursY, 1, 'filter')
smooth_contours_xld (ContoursY, SmoothedContoursY, 151)
segment_contours_xld (SmoothedContoursY, ContoursSplitY, 'lines', 5, 4, 2)
regress_contours_xld (ContoursSplitY, RegressContoursY, 'no', 1)
union_straight_contours_xld (RegressContoursY, UnionContoursY, 500, 0.5, 50, 'noparallel', 'maximum')
fit_line_contour_xld (UnionContoursY, 'tukey', -1, 0, 5, 2, RowBegin1, ColBegin1, RowEnd1, ColEnd1, Nr1, Nc1, Dist1)
gen_region_line (RegionLinesY, RowBegin1, ColBegin1, RowEnd1, ColEnd1)
count_obj (UnionContoursY, NumberY)
if(NumberY # 1)
dev_disp_text ('未找到左边缘', 'window', 12, 12, 'black', 'box_color', '#fce9d4dd')
stop ()
endif
if(ColBegin1 < ColEnd1)
gen_arrow_contour_xld (ArrowY, RowEnd1, ColEnd1, RowBegin1, ColBegin1, 50, 50)
else
gen_arrow_contour_xld (ArrowY, RowBegin1, ColBegin1, RowEnd1, ColEnd1, 50, 50)
endif
*****6、检测大小灰尘处理 ******************
* 矩形腐蚀(边缘不处理)
erosion_rectangle1 (SelectedRegionsT, RegionErosionRoi, 12, 12)
* 聚焦内部区域
reduce_domain (Image, RegionErosionRoi, ImageReducedT)
* 二值化 处理大灰尘
threshold (ImageReducedT, RegionTp, 128, 255)
* 动态阈值处理 小灰尘
mean_image (ImageReducedT, ImageMean, 7, 7)
dyn_threshold (ImageReducedT, ImageMean, RegionDynThreshSmall, 5, 'light')
* 合并 大小灰尘
union2 (RegionTp, RegionDynThreshSmall, RegionUnionAll)
* 连通域打散分析
connection (RegionUnionAll, ConnectedRegions1)
* 闭运算
closing_circle (ConnectedRegions1, RegionClosing, 3.5)
* 连通域过滤 (去除面积小于3)
select_shape (RegionClosing, SelectedRegions3, 'area', 'and', 3, 9999999)
*****7、过滤边缘与杂质 ******************
* 过滤边框处理
erosion_circle (RegionErosionRoi, RegionErosionRoi, 1.5)
* 交集 (内框区域,大小灰尘区域 = 内部大小灰尘区域)
intersection (RegionErosionRoi, SelectedRegions3, SelectedRegions3)
* 连通域分析
connection (SelectedRegions3, ConnectedRegions2)
* 统计灰尘个数
count_obj (ConnectedRegions2, NumberP)
dev_clear_window ()
dev_display (Image)
* 杂质过滤
* 空的确认灰尘列表
gen_empty_obj (ParticalRegion)
* 循环读取灰尘
for Index := 1 to NumberP by 1
* 选择一个灰尘
select_obj (ConnectedRegions2, ObjectSelected, Index)
* 圆形膨胀
dilation_circle (ObjectSelected, RegionDilationS, 3.5)
* 减法获取灰尘周围区域(膨胀后区域 - 灰尘区域 = 灰尘周围区域)
difference (RegionDilationS, ObjectSelected, RegionDifferenceS)
* 计算灰尘周围灰度
intensity (RegionDifferenceS, Image, MeanS, DeviationS)
* 计算灰尘内部灰度
intensity (ObjectSelected, Image, MeanSP, DeviationSP)
* 周围灰度 - 内部灰度 = 内外灰度差
DeltaGray := MeanSP - MeanS
* 中心点与面积
area_center (ObjectSelected, Area, Row, Column)
* 绘制十字
gen_cross_contour_xld (Cross, Row, Column, 30, 0.785398)
* 如果灰度差大于8 说明是灰尘
if(DeltaGray > 8)
* 保存至灰尘列表
concat_obj (ParticalRegion, ObjectSelected, ParticalRegion)
endif
endfor