因为太多的博客并没有深入理解,本文是自己学习后加入自己深入理解的总结记录,方便自己以后查看
Halcon模板匹配、阈值分割、仿射变换的运用
学习前言
一起来学习Halcon做实战项目---螺丝检测
参考链接:无
一、检测出下图中螺丝的有无
。
二、算法流程思路
- BGRToGrey
- 做高斯变换算法平滑(效果不理想)
- 像素特征提取映射(0-20,20-255)
- 整个物体特征轮廓提取做精定位确定每个孔位置(图片不完善)
- 模板匹配卷积平滑匹配无螺丝时候的孔特征,得到无螺丝匹配分数
- 模板匹配卷积平滑匹配有螺丝时候的十字特征,得到有螺丝匹配分数
- 确定螺丝孔直径20piex内的像素平均值,低像素比例值
- 通过设置无螺丝匹配分数范围,有螺丝匹配分数范围,像素平均值范围,低像素比例值范围确定有无螺丝结果
- 结果显示仿射变换
注意点:
1、如果上线后图片阈值波动较大,换成使用检测区域平均像素来做直方图分割
1.创建模板代码
dev_close_window ()
dev_update_off ()
********创建模型**********
read_image (Image, 'D:/AllLargeProject/找螺丝项目/InputImage/1.jpg')
rgb1_to_gray (Image, Image)
get_image_size (Image, Width, Height)
threshold (Image, Region1, 1, 20)
*binary_threshold (Image, Region1, 'max_separability', 'dark', UsedThreshold)
*region_to_mean (Region1, Image, Region1)
region_to_bin (Region1, Image, 255, 0, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_display (Image)
*选取模型区域(模型效果不好时可以自己画出模型特征图后再建)
draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)
gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)
reduce_domain (Image, Rectangle, ImageReduced)
threshold (ImageReduced, Region, 0, 30)
connection (Region, ConnectedRegions)
area_center (ConnectedRegions, Area, Row3, Column3)
select_shape_std (ConnectedRegions, SelectedRegions, 'max_area', 70)
dilation_circle (SelectedRegions, RegionDilation, 5.5)
fill_up (RegionDilation, RegionFillUp)
reduce_domain (ImageReduced, RegionFillUp, ImageReduced2)
ImageReduced:=ImageReduced2
inspect_shape_model (ImageReduced, ModelImages, ModelRegions, 8, 30)
*创建模型
create_scaled_shape_model (ImageReduced, 5, rad(0), rad(360), 'auto', 0.8, 1.2, 'auto', 'auto', 'use_polarity', 30, 4, ModelID)
*create_scaled_shape_model (ImageReduced, 'auto', rad(0), rad(360), 'auto', 0.9, 1.1, 'auto', 'auto', 'ignore_global_polarity', 'auto', 'auto', ModelID)
get_shape_model_params (ModelID, NumLevels, AngleStart, AngleExtent, AngleStep, ScaleMin, ScaleMax, ScaleStep, Metric, MinContrast)
*保存模型
write_shape_model(ModelID, 'D:/AllLargeProject/找螺丝项目/孔特征.shm')
************模型测试**********
list_files ('D:/AllLargeProject/找螺丝项目', 'files', Files)
for Index := 0 to |Files| by 1
if (Index=|Files|)
Index := |Files|-1
endif
read_image (Image1, Files[Index])
rgb1_to_gray (Image1, Image1)
get_image_size (Image1, Width, Height)
threshold (Image1, Region11, 1, 20)
region_to_bin (Region11, Image1, 255, 0, Width, Height)
dev_display (Image1)
draw_rectangle1 (WindowHandle, Row11, Column11, Row21, Column21)
gen_rectangle1 (Rectangle1, Row11, Column11, Row21, Column21)
reduce_domain (Image1, Rectangle1, ImageReduced1)
*find_scaled_shape_model (ImageReduced1, ModelID, rad(0), rad(360), 0.9, 1.1, 0.5, 1, 0.8, 'least_squares', 0, 0.7, Row, Column, Angle, Scale, Score)
find_scaled_shape_model (ImageReduced1, ModelID, rad(0), rad(360), 0.99, 1.01, 0.4, 1, 0.8, 'least_squares', 0, 0.7, Row, Column, Angle, Scale, Score)
dev_display_shape_matching_results (ModelID, 'red', Row, Column, Angle, 1, 1, 0)
get_shape_model_contours (ModelContours, ModelID, 1)
hom_mat2d_identity (HomMat2DIdentity) //仿射变换矩阵
hom_mat2d_rotate (HomMat2DIdentity, Angle, 0, 0, HomMat2DRotate) //旋转变换
hom_mat2d_translate (HomMat2DRotate, Row, Column, HomMat2DTranslate) //平移变换
affine_trans_contour_xld (ModelContours, ContoursAffineTrans, HomMat2DTranslate)//对轮廓进行仿射变换矩阵
dev_clear_window ()
stop()
endfor
2.螺丝检测代码
dev_get_window(WindowHandle)
********************初始化********************
*导入模型
read_shape_model ('D:/AllLargeProject/找螺丝项目/孔特征.shm', ModelID_Kong)
read_shape_model ('D:/AllLargeProject/找螺丝项目/十字特征.shm', ModelID_ShiZi)
*提取特征
get_shape_model_contours (ModelKongContours, ModelID_Kong, 1)
get_shape_model_contours (ModelShiZiContours, ModelID_ShiZi, 1)
*匹配开始角度
AngleStart := 0
*匹配结束角度
AngleEnd := 0
*匹配缩放比例
ScaleMin := 0.9
*匹配缩放比例
ScaleMax := 1.1
*遍历文件夹路径
list_files ('D:/AllLargeProject/找螺丝项目/InputImage', 'files', Files)
********************螺丝检测********************
for Index := 0 to |Files| by 1
if (Index=|Files|)
Index := 0
endif
read_image (InputImage, Files[Index])
*BGRtoGrey
rgb1_to_gray (InputImage, InputImage)
get_image_size (InputImage, Width, Height)
*阈值分割
threshold (InputImage, tRegion, 1, 20)
*像素映射后图片
region_to_bin (tRegion, Image, 255, 0, Width, Height)
dev_display (InputImage)
dev_set_draw ('margin')
*draw_rectangle1 (WindowHandle, Row111, Column111, Row211, Column211)
*******检测区域********
if(Index == 0)
DetectRegionRow1 := [11,644]
DetectRegionColumn1 := [300,38]
DetectRegionRow2 := [55,700]
DetectRegionColumn2 := [347,93]
endif
if(Index == 1)
DetectRegionRow1 := [26,353,655]
DetectRegionColumn1 := [406,66,145]
DetectRegionRow2 := [74,398,702]
DetectRegionColumn2 := [459,117,191]
endif
*显示字体步长
step := 20
a :=|DetectRegionRow1|
*遍历检测区域
for Index1 := 0 to |DetectRegionRow1|-1 by 1
gen_rectangle1 (Rectangle, DetectRegionRow1[Index1], DetectRegionColumn1[Index1], DetectRegionRow2[Index1], DetectRegionColumn2[Index1])
reduce_domain (Image, Rectangle, ImageReduced)
dev_display (Rectangle)
*******模型特征卷积匹配********
find_scaled_shape_model (ImageReduced, ModelID_Kong, rad(AngleStart), rad(AngleEnd), ScaleMin, ScaleMax, 0.4, 1, 0.8, 'least_squares', 0, 0.7, Row_Kong, Column_Kong, Angle_Kong, Scale_Kong, Score_Kong)
find_scaled_shape_model (ImageReduced, ModelID_ShiZi, rad(AngleStart), rad(AngleEnd), ScaleMin, ScaleMax, 0.4, 1, 0.8, 'least_squares', 0, 0.7, Row_ShiZi, Column_ShiZi, Angle_ShiZi, Scale_ShiZi, Score_ShiZi)
******************************结果判定-可根据实际情况修改***************
if(Score_ShiZi>0.6)
***二维仿射变换***
*创建矩阵
hom_mat2d_identity (HomMat)
*旋转变换
hom_mat2d_rotate (HomMat, Angle_ShiZi[0], 0, 0, HomMat)
*平移变换
hom_mat2d_translate (HomMat, Row_ShiZi[0], Column_ShiZi[0], HomMat)
*匹配特征显示
affine_trans_contour_xld (ModelShiZiContours, TransShiZiContours, HomMat)
dev_display (TransShiZiContours)
dev_set_color('green')
*字体显示
set_tposition (WindowHandle, DetectRegionRow1[Index1],DetectRegionColumn2[Index1]+step)
write_string (WindowHandle, 'OK')
set_tposition (WindowHandle, DetectRegionRow1[Index1]+step,DetectRegionColumn2[Index1]+step)
write_string (WindowHandle, '有螺丝')
set_tposition (WindowHandle, DetectRegionRow1[Index1]+2*step,DetectRegionColumn2[Index1]+step)
write_string (WindowHandle, 'Score_Kong:')
set_tposition (WindowHandle, DetectRegionRow1[Index1]+2*step,DetectRegionColumn2[Index1]+5*step)
write_string (WindowHandle, Score_Kong)
set_tposition (WindowHandle, DetectRegionRow1[Index1]+3*step,DetectRegionColumn2[Index1]+step)
write_string (WindowHandle, 'Score_ShiZi:')
set_tposition (WindowHandle, DetectRegionRow1[Index1]+3*step,DetectRegionColumn2[Index1]+5*step)
write_string (WindowHandle, Score_ShiZi)
else
if(Score_Kong>0.6)
hom_mat2d_identity (HomMat)
hom_mat2d_rotate (HomMat, Angle_Kong[0], 0, 0, HomMat)
hom_mat2d_translate (HomMat, Row_Kong[0], Column_Kong[0], HomMat)
affine_trans_contour_xld (ModelKongContours, TransKongContours, HomMat)
dev_display (TransKongContours)
endif
dev_set_color('red')
set_tposition (WindowHandle, DetectRegionRow1[Index1],DetectRegionColumn2[Index1]+step)
write_string (WindowHandle, 'NG')
set_tposition (WindowHandle, DetectRegionRow1[Index1]+step,DetectRegionColumn2[Index1]+step)
write_string (WindowHandle, '无螺丝')
set_tposition (WindowHandle, DetectRegionRow1[Index1]+2*step,DetectRegionColumn2[Index1]+step)
write_string (WindowHandle, 'Score_Kong:')
set_tposition (WindowHandle, DetectRegionRow1[Index1]+2*step,DetectRegionColumn2[Index1]+5*step)
write_string (WindowHandle, Score_Kong)
set_tposition (WindowHandle, DetectRegionRow1[Index1]+3*step,DetectRegionColumn2[Index1]+step)
write_string (WindowHandle, 'Score_ShiZi:')
set_tposition (WindowHandle, DetectRegionRow1[Index1]+3*step,DetectRegionColumn2[Index1]+5*step)
write_string (WindowHandle, Score_ShiZi)
endif
endfor
endfor
请用Halcon编辑器打开