跳一跳中从skeleton骨架里拟合椭圆
By
admin
at 2018-02-25 • 0人收藏 • 2256人看过

跳一跳中有圆形的跳板, 嗯,不对,是椭圆形的跳板.
我们通过骨架获得到的边界需要进行椭圆模拟,然后找到中心点
read_image (Image, 'C:/Users/Administrator/Desktop/halcon_T1T/testsave.png') dev_close_window () dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle) dev_display (Image) //因为事先处理图片为边界黑色,所以只选择黑色部分 threshold (Image, Regions, 0, 200) //膨胀选中的全部线段:使每个像素点都链接起来,成为一个完整的不断的线条 dilation_rectangle1 (Regions, RegionDilation, 30, 30) //抽取膨胀后的粗线条的骨架 skeleton (RegionDilation, Skeleton) //把图片中的所有曲线联合分离 connection (Skeleton, ConnectedRegions) //选中准备拟合的这个线段 select_obj (ConnectedRegions, ObjectSelected2, 2) //将骨架转换为xld线 gen_contours_skeleton_xld (ObjectSelected2, Contours, 1, 'filter') //把xld线拆分为线和圆弧 segment_contours_xld (Contours, ContoursSplit, 'lines_ellipses', 5, 4, 2) //对这些弧线进行排序,按照"行"先后排序,这样跳跳里面这个应该是最上面的 sort_contours_xld (ContoursSplit, SortedContours, 'upper_left', 'true', 'row') //选择最上面那个弧线 select_obj (SortedContours, ObjectSelected3, 1) //拟合为椭圆 fit_ellipse_contour_xld (ObjectSelected3, 'fitzgibbon', -1, 0, 0, 200, 3, 2, Row3, Column3, Phi1, Radius1, Radius2, StartPhi, EndPhi, PointOrder) //绘制椭圆 gen_ellipse_contour_xld (ContEllipse, Row3, Column3, Phi1, Radius1, Radius2, 0, 6.28318, 'positive', 1.5) //画出椭圆中心点 disp_cross (WindowHandle, Row3, Column3, 50, 0)
2 个回复 | 最后更新于 2018-02-25
另外一种写法:
这种适应性差,只为学习用
将图片进行灰度之后,阈值缩放加深对比色,然后利用灰度方块统一色调,整个画面图形就全是黑色了,然后找边缘...这里就又问题了.边缘有些顺序不一致.....
//
var ret,Image1, Image2, Image3 = halconc.decompose3 (gameImage, 0,0,0);
var ret,ROI_0 = halconc.gen_rectangle1 (0, 218.498, 2.83828, 1223.44, 746.162);
var ret,ImageReduced = halconc.reduce_domain (Image3, ROI_0, 0);
var flag = 0;
for(y=219;1223;1){
var ret,base_Grayval = halconc.get_grayval (ImageReduced, y, 3, 0)
for(x=3;745;1){
var ret,single_Grayval = halconc.get_grayval (ImageReduced, y, x, 0)
var dec_val = math.abs(single_Grayval-base_Grayval)
if(dec_val!=0){
//if(flag ==0){
var ret = halconc.set_grayval (ImageReduced, y, x, 0)
//}else {
// var ret = halconc.set_grayval (ImageReduced, y, x, 255)
//}
//flag ++;
}else {
//if(flag != 0){
// var ret = halconc.set_grayval (ImageReduced, y, x-1, 0)
// flag = 0;
//}else {
var ret = halconc.set_grayval (ImageReduced, y, x, 255)
//}
}
}
}
var ret,ImageMin1 = halconc.gray_erosion_rect (ImageReduced, 0, 8, 8)
var ret = halconc.disp_obj(ImageMin1,Hwindow);
var ret,Edges1 = halconc.edges_sub_pix (ImageMin1, 0, 'canny', 1, 20, 40)
var ret,ContoursSplit = halconc.segment_contours_xld (Edges1, 0, 'lines_ellipses', 5, 4, 2)
var ret,SortedContours = halconc.sort_contours_xld (ContoursSplit, 0, 'upper_left', 'true', 'row')
var ret,ObjectSelected = halconc.select_obj (SortedContours, 0, 9)
var ret = halconc.set_color(Hwindow,"magenta");
var ret = halconc.set_line_width(Hwindow,3);
var ret = halconc.disp_obj(ObjectSelected,Hwindow);登录后方可回帖
下面是找图片中方形物体的中心点:(圆形点的是上面的,但是怎么判断是方的或者是圆的??)
import halconc; //console.open(); //首先设置默认背景图像 var ret,BGImage = halconc.read_image(0,"res/bg"); var ret,width,height = halconc.get_image_size(BGImage,0,0); var ret,Hwindow = halconc.open_window(0,0,width,height,mainForm.picturebox.hwnd,"visible", "",0); var ret = halconc.disp_obj(BGImage,Hwindow); var pathnum = 7; mainForm.button.oncommand = function(id,event){ if(pathnum >= 18){ pathnum = 1; }else { pathnum ++; } //win.delay(1000) //var ret = halconc.set_draw(Hwindow,"margin"); //var ret = halconc.set_color(Hwindow,"green"); //调用演示图像 var ret,gameImage = halconc.read_image(0,"res/tt" ++ pathnum); //灰度化 var ret,BGGrayImage = halconc.rgb1_to_gray(BGImage, 0); var ret,gameGrayImage = halconc.rgb1_to_gray(gameImage, 0); //找小人坐标 var ret,xiaorenImageScaled = halconc.scale_image (gameGrayImage, 0, 7.72727, -394); var ret,xiaorenRegions = halconc.threshold (xiaorenImageScaled, 0, 0, 253) var ret,xiaorenRegionErosion = halconc.erosion_circle(xiaorenRegions,0,15); var ret,xiaorenRegionFillUp = halconc.fill_up (xiaorenRegionErosion, 0); var ret,xiaorenArea, xiaorenRow1, xiaorenColumn1 = halconc.area_center (xiaorenRegionFillUp, 0,0,0); var ret = halconc.set_color(Hwindow,"magenta"); var ret = halconc.set_line_width(Hwindow,3); var ret,xiaorenCross = halconc.gen_cross_contour_xld (0, xiaorenRow1, xiaorenColumn1, 50, 0.785398); var ret = halconc.disp_obj(gameGrayImage,Hwindow); var ret = halconc.disp_obj(xiaorenCross,Hwindow); //获取三通道 var ret,Image1, Image2, Image3 = halconc.decompose3 (gameImage, 0,0,0); //手动绘制ROI var ret,ROI_0 = halconc.gen_rectangle1 (0, 218.498, 2.83828, 1223.44, 746.162); //截图 var ret,ImageReduced = halconc.reduce_domain (Image3, ROI_0, 0); var flag = 0; //获取图片左边第一个点的灰度值作为基准,连续取后面的灰度值,相减判断 for(y=219;1223;1){ var ret,base_Grayval = halconc.get_grayval (ImageReduced, y, 3, 0) for(x=3;745;1){ var ret,single_Grayval = halconc.get_grayval (ImageReduced, y, x, 0) var dec_val = math.abs(single_Grayval-base_Grayval) //不是背景色 if(dec_val!=0){ if(flag ==0){ var ret = halconc.set_grayval (ImageReduced, y, x, 0) }else { var ret = halconc.set_grayval (ImageReduced, y, x, 255) } flag ++; }else { //是背景色 if(flag != 0){ var ret = halconc.set_grayval (ImageReduced, y, x-1, 0) flag = 0; }else { var ret = halconc.set_grayval (ImageReduced, y, x, 255) } } } } //var ret = halconc.disp_obj(ImageReduced,Hwindow); //win.delay(5000) //和上面的圆弧获取一样功能 var ret,Regions = halconc.threshold (ImageReduced, 0, 0, 200) var ret,RegionDilation = halconc.dilation_rectangle1 (Regions, 0, 10, 10) // var ret = halconc.disp_obj(RegionDilation,Hwindow); var ret,Skeleton = halconc.skeleton (RegionDilation, 0) var ret,ConnectedRegions = halconc.connection (Skeleton, 0) var ret,SortedRegions = halconc.sort_region (ConnectedRegions, 0, 'first_point', 'true', 'row') var ret,ObjectSelected = halconc.select_obj (SortedRegions, 0, 2) var ret,RegionLines = halconc.split_skeleton_region (ObjectSelected, 0, 20) var ret,SortedRegions = halconc.sort_region (RegionLines, 0, 'first_point', 'true', 'row') var ret,ObjectSelected1 = halconc.select_obj (SortedRegions, 0, 2) //获取选中region的角度 var ret,Phi = halconc.orientation_region (ObjectSelected1, 0) //获取这条线的中心点坐标 var ret,Area, Row, Column = halconc.area_center (ObjectSelected1, 0,0,0) var ret,zhongdianCross = halconc.gen_cross_contour_xld (0, Row, Column, 50, 0); //var ret = halconc.disp_obj(zhongdianCross,Hwindow); //通过绘制最小矩形,来获取到线段的顶点坐标 var ret,Row1, Column1, Row2, Column2 = halconc.smallest_rectangle1 (ObjectSelected1, 0,0,0,0) //下面的这个函数用不了,所以只能用上面的方式获取顶点坐标 //var ret,BeginRow, BeginCol, EndRow, EndCol = halconc.T_split_skeleton_lines (ObjectSelected1, 3, 0,0,0,0) //绘制跳板中心十字线(顶点行坐标-中心点行坐标,列坐标不变) var ret,tiaobanCross = halconc.gen_cross_contour_xld (0, Row1 + 2*(Row - Row1), Column1, 50, 0); var ret = halconc.disp_obj(tiaobanCross,Hwindow); }