Halcon学习一:骰子识别
cpp
get_system('image_dir',ImageSearchPath)
**关窗
dev_close_window()
**读影像
read_image(Image,'dice')
**获取影像尺寸
get_image_size(Image,imgw,imgh)
**按照原图尺寸打开可视化界面
dev_open_window(0,0,imgw,imgh,'black',winhandle)
**显示影像
dev_display(Image)
**停
stop()
**影像通道数获取
count_channels(Image,channels)
**彩色转灰度
if(channels ==3)
rgb1_to_gray(Image,GrayImage)
else
copy_image(Image,GrayImage)
endif
**硬阈值二值化
**threshold(GrayImage,region,150,255)
**最大类间差法获取前景 亮区
binary_threshold(GrayImage,region,'max_separability','light',UsedThreshold)
**填充区域内部的区域
* fill_up(region, RegionFillUp)
**分离连通域
connection(region, ConnectedRegions)
**获取区域数量
count_obj(ConnectedRegions, Number)
**按照面积筛选分割区域
select_shape(ConnectedRegions, SelectedRegions, 'area', 'and', 15000, 99999999)
**重新筛选一次
count_obj(SelectedRegions, Number)
dev_display(SelectedRegions)
**清空屏幕
dev_clear_window()
**显示相关
dev_display(Image)
* dev_set_draw('margin')
* dev_set_line_width(3)
* dev_set_color('green')
dev_display(SelectedRegions)
**计算骰子中心点
area_center(SelectedRegions, Area, Row, Column)
**依次遍历绘制
for Index := 1 to Number by 1
disp_message(winhandle, Index, 'image', Row[Index - 1], Column[Index - 1] - 10, 'green', 'true')
endfor
stop()
** ----------------识别骰子数字是几
dev_clear_window()
dev_display(Image)
dev_set_draw('margin')
dev_set_line_width(3)
dev_set_color('green')
dev_display(SelectedRegions)
**------------------------直接求最小外接圆----------------------
* 生成一个空的元组
* gen_empty_obj(EmptyObject)
* for Index := 1 to Number by 1
*获取当前骰子的区域
* select_obj(SelectedRegions, CurrentDice, Index)
*求当前骰子的实心区域
* fill_up(CurrentDice, CurrentDiceFilled)
*实心 - 带孔 = 当前骰子内部的黑点
* difference(CurrentDiceFilled, CurrentDice, Dots)
* 过滤极小的噪点并分离
* connection(Dots, ConnectedDots)
* select_shape(ConnectedDots, FinalDots, 'area', 'and', 20, 2000)
*统计点数
* count_obj(FinalDots,dotnum)
*收集数据
* concat_obj(EmptyObject,FinalDots,EmptyObject)
*显示点数
* area_center(CurrentDice,Area1, Row1, Column1)
* disp_message(winhandle, dotnum, 'Image', Row1, Column1, 'red', 'true')
* endfor
**绘制内部的圆
*最小内接圆
* smallest_circle(EmptyObject,Row2, Column2, Radius)
*生成圆轮廓
* gen_circle_contour_xld(circles,Row2, Column2, Radius, 0, 6.28318, 'positive', 1)
* dev_set_color('red')
* dev_set_line_width(2)
* dev_display(circles)
**------------------------亚像素最小二乘拟合圆----------------------
** 设置字体 字体大小 格式 是否加粗 是否倾斜
set_display_font(winhandle, 16, 'mono', 'true', 'false')
TextY := 20
TextX := 10
disp_message(winhandle, 'Total Dice Count: ' + Number, 'window', TextY, TextX, 'yellow', 'false')
TextY := TextY + 30
*生成空的元组
gen_empty_obj(EmptyObject01)
gen_empty_obj(AllCircleBorder)
*开始遍历每个骰子
for Index1 := 1 to Number by 1
*筛选当前骰子的区域
select_obj(SelectedRegions,CurrentDice,Index1)
*填充骰子内部区域
fill_up(CurrentDice,FillRegion)
*做差
difference(FillRegion,CurrentDice,RegionDifference)
*区域连通性分析
connection(RegionDifference, ConnectedRegions1)
*面积筛选
select_shape(ConnectedRegions1,SelectedRegions1, 'area', 'and', 20, 1500)
*重新计算有效点数量
count_obj(SelectedRegions1,CurrDiceNum)
*存一下当前的结果
concat_obj(EmptyObject01,SelectedRegions1,EmptyObject01)
*获取一下骰子的中心
area_center(CurrentDice, Area1, Row1, Column1)
*显示一下骰子的中心和数字
disp_message(winhandle, CurrDiceNum, 'image', Row1, Column1, 'red', 'true')
*窗体左上角显示当前信息
StrDiceInfo := 'Dice' + Index1 + '[Center: ( ' + Row1$'.2f' + ', ' + Column1$'.2f' + '), Num : ' + CurrDiceNum + ']'
disp_message(winhandle, StrDiceInfo, 'window', TextY, TextX, 'red', 'true')
TextY := TextY + 30
*开始内层循环
for Index2 := 1 to CurrDiceNum by 1
*提取每个黑点区域
select_obj(SelectedRegions1,SinalDot,Index2)
*将黑点转为亚像素变换轮廓
gen_contour_region_xld(SinalDot, Contours, 'border')
*开始拟合圆
fit_circle_contour_xld(Contours,'algebraic', -1, 0, 0, 5, 2, Row2, Column2, Radius, StartPhi, EndPhi, PointOrder)
*生成轮廓
gen_circle_contour_xld(ContCircle, Row2, Column2, Radius, 0, 6.28318, 'positive', 1)
*收集论库 统一绘制
concat_obj(AllCircleBorder, ContCircle, AllCircleBorder)
*打印字符串
StrDotInfo := ' - Dot ' + Index2 + ': Center(' + Row2$'.1f' + ', ' + Column2$'.1f' + '), R: ' + Radius$'.2f'
disp_message(winhandle, StrDotInfo, 'window', TextY, TextX + 20, 'white', 'false')
TextY := TextY + 30
endfor
TextY := TextY + 30
endfor
*开始绘制
dev_set_color('red')
dev_set_line_width(2)
dev_display(AllCircleBorder)
stop()

