返回首页 hi, 欢迎来到机器人在线 请登录/ 免费注册 扫码关注

机器人视觉--浅谈单相机贴合

时间:2020-06-09 来源:机器人在线 阅读:17499

思路:

建模板--9点标定求出像素比--求旋转中心---匹配实际抓取到的产品---计算出机械手补偿

9点标定求出像素比


第一步采集图像:


HOperatorSet.GrabImageAsync(out ho_Image1, hv_AcqHandle, -1);

HDevWindowStack.SetActive(hv_WindowHandle);

HOperatorSet.MirrorImage(ho_Image1, out ho_ImageMirror, "row");

HOperatorSet.MirrorImage(ho_ImageMirror, out ho_ImageMirror1, "column");

HOperatorSet.GetImageSize(ho_ImageMirror1, out hv_Width, out hv_Height);

if (HDevWindowStack.IsOpen())

{

HOperatorSet.SetPart(HDevWindowStack.GetActive(), 0, 0, hv_Height, hv_Width);

}//实际使用需要注意图像显示前 设置当前活跃窗口

if (HDevWindowStack.IsOpen())

{

HOperatorSet.DispObj(ho_ImageMirror1, HDevWindowStack.GetActive());

}


第二步获得九点的位置:


HOperatorSet.MirrorImage(ho_Image1, out ho_ImageMirror, "row");

HOperatorSet.MirrorImage(ho_ImageMirror, out ho_ImageMirror1, "column");

HOperatorSet.Rgb1ToGray(ho_ImageMirror1, out ho_GrayImage);

HOperatorSet.ScaleImage(ho_GrayImage, out ho_ImageScaled, 2.07317, 0);

HOperatorSet.Threshold(ho_ImageScaled, out ho_Regions, t_min, t_max);

HOperatorSet.Connection(ho_Regions, out ho_ConnectedRegions);

HOperatorSet.SelectShape(ho_ConnectedRegions,outho_SelectedRegions1,(new HTuple("area")).TupleConcat( "circularity"), "and", (new HTuple(600)).TupleConcat(0.5422), (new HTuple(8486.24)).TupleConcat(1));

HOperatorSet.SortRegion(ho_SelectedRegions1, out ho_SortedRegions, "character","true", "row");

HOperatorSet.ShapeTrans(ho_SortedRegions, out ho_RegionTrans, "outer_circle");

HOperatorSet.AreaCenter(ho_RegionTrans, out hv_Area, out hv_Row, out hv_Column);

PS:需要注意的地方,根据实际情况使用MirrorImage,标定时使用的MirrorImage,识别时候一定要使用,否则一定会不准;经过预处理得到九点的行列坐标为:hv_Row,hv_Column。


第三步:获取到机械手的实际九点位置(此处可以与机器人通信获得)


机械手X坐标值:

hv_x[0] = 24;

hv_x[1] = 24;

hv_x[2] = 24;

hv_x[3] = 39;

hv_x[4] = 39;

hv_x[5] = 39;

hv_x[6] = 38;

hv_x[7] = 38;

hv_x[8] = 38;

机械手Y坐标值:

hv_y[0] = 42;

hv_y[1] = 71;

hv_y[2] = 86;

hv_y[3] = 46;

hv_y[4] = 75;

hv_y[5] = 92;

hv_y[6] = 48;

hv_y[7] = 80;

hv_y[8] = 96;

HOperatorSet.VectorToHomMat2d(hv_Column,hv_Row,hv_y,hv_x,outv_HomMat2D);//根据像素坐标和机械手坐标求出矩阵,获得相应之间的关系。


第四步:采集图像,如第一步一致不在阐述


第五步:处理图像(这里是灵活的目的是得到需要的检测的物体坐标,这里只是给出了一个简单的blob分析得到的坐标位置,大家可以灵活的去实现图像处理方法。)


HOperatorSet.GrabImageAsync(out ho_Image, Form_biaoding.hv_AcqHandle, -1); //采集图像

HDevWindowStack.SetActive(hv_WindowHandle);//设置当前窗口

HOperatorSet.Rgb1ToGray(ho_Image, out ho_GrayImage);

HOperatorSet.MirrorImage(ho_GrayImage, out ho_ImageMirror, "row");

HOperatorSet.MirrorImage(ho_ImageMirror, out ho_ImageMirror1, "column");

HOperatorSet.GetImageSize(ho_ImageMirror1, out hv_Width, out hv_Height);//获得图像尺寸

if (HDevWindowStack.IsOpen())

{

HOperatorSet.SetPart(HDevWindowStack.GetActive(), 0, 0, hv_Height, hv_Width);

}

HOperatorSet.Threshold(ho_ImageMirror1, out ho_Regions, t_min, t_max);

HOperatorSet.OpeningCircle(ho_Regions, out ho_RegionOpening, 1.5);

HOperatorSet.Connection(ho_RegionOpening, out ho_ConnectedRegions);

HOperatorSet.SelectShape(ho_ConnectedRegions, out ho_SelectedRegions, "area",

"and", area_min, area_max);

 HOperatorSet.ShapeTrans(ho_SelectedRegions, out ho_RegionTrans, "outer_circle");

HOperatorSet.AreaCenter(ho_RegionTrans, out hv_Area, out hv_Row, out hv_Column);

if (HDevWindowStack.IsOpen())

{

HOperatorSet.DispObj(ho_ImageMirror1, HDevWindowStack.GetActive());

}

if (HDevWindowStack.IsOpen())

{

HOperatorSet.DispObj(ho_RegionTrans, HDevWindowStack.GetActive());

}

PS:这部分主要是为了得到像素的行列坐标值


第六步:求得实际坐标

HOperatorSet.AffineTransPoint2d(hv_hv_HomMat2D, hv_Column, hv_Row, out hv_Qy,out hv_Qx);//根据像素坐标得到的实际机械手坐标值(hv_Qy,hv_Qx)


求旋转中心(三点拟合求圆)

==================CSharp实现================

public bool FitCircle(double[] X, double[] Y, out double RcX, out double RcY, out double R)

 {

  try

  {

   HTuple hTuple = new HTuple();

   HTuple hTuple2 = new HTuple();

   int num = 0;

   for (num = 0; num < X.Length; num++)

   {

    if ((X[num] > 0.0) & (Y[num] > 0.0))//获得寻找到的模板中心装入hTuple2与hTuple

    {

                    hTuple2.TupleConcat(X[num]);

                    hTuple.TupleConcat(Y[num]);

    }

   }

   HObject contour;

   HOperatorSet.GenContourPolygonXld(out contour, hTuple, hTuple2);//使用模板中心生成多边形XLD轮廓

   HTuple row, column,radius,StartPhi,EndPhi,pointOrder;

   HOperatorSet.FitCircleContourXld(contour, "algebraic", -1, 0, 0, 3, 2, out  row, out  column, out  radius, out StartPhi, out EndPhi, out pointOrder);//拟合圆形

   //得出结果

   RcY = row;

   RcX = column;

   R = radius;


            contour.Dispose();

   return true;

  }

  catch

  {

   RcY = -1.0;

   RcX = -1.0;

   R = -1.0;

   return false;

  }

 }

==================Halcon实现=============

dev_set_line_width (1)

dev_set_draw ('margin')

*确定三个点,在窗口上用鼠标点三个点

draw_point (3600, Row1, Column1)

draw_point (3600, Row2, Column2)

draw_point (3600, Row3, Column3)

Rows :=[Row1,Row2,Row3]

Cols :=[Column1,Column2,Column3]

dev_set_color ('red')

gen_contour_polygon_xld (Contour, Rows, Cols)

*stop ()

*拟合一个圆

fit_circle_contour_xld (Contour, 'geotukey', -1, 0, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)

*创建圆弧xld

gen_circle_contour_xld (ContCircle, Row, Column, Radius, StartPhi, EndPhi, 'negative', 1)

distance_pc (ContCircle, Row2, Column2, DistanceMin, DistanceMax)

*判断第三点在不在拟合的弧线上面,这一步主要用点的顺序确定圆弧的其实位置

if (DistanceMin>1)

    gen_circle_contour_xld (ContCircle, Row, Column, Radius, StartPhi, EndPhi,  'positive', 1)

endif

dev_clear_window ()

dev_display (ContCircle)

stop ()

*以下是拟合一个整圆

gen_circle_contour_xld (ContCircle1, Row, Column, Radius, 0, 6.28318, 'positive', 1)

求实际发给机器人补偿值


===================第一种=================

*modelRow,modelCol,modelAngle为模板中心,模板中心的角度一般是0,求模板中心也可以用建立模板的图片匹配一次 

*rotateRow,rotateCol为旋转中心(不带角度),可以理解为吸头中心

*matchRow,matchCol,matchAngle为匹配到的中心 

*下面是向量运算,刚性仿射变换(这个需要好好理解) 

vector_angle_to_rigid(modelRow,modelCol,modelAngle,matchRow,matchCol,matchAngle,HomMat2D) 

*下面把旋转中心带进去进行仿射变化 

affine_trans_point_2d(HomMat2D,rotateRow,rotateCol,Qx, Qy) 

*下面得到机械手要补偿的数据

dltRow:=rotateRow-Qx 

dltCol:=rotateCol-Qy 

dltAngle:=matchAngle-modelAngle

===============END 第一种==================


================第二种=====================

1、 旋转中心为:RectCenter_Row, RectCenter_Column

2、基准模板图像中Mark的中心点:ModelRow, ModelCol

3、拍摄得到的Mark新的中心点:Row,Column   角度:Angle

hom_mat2d_identity(HomMat2DIdentity3)

  hom_mat2d_rotate(HomMat2DIdentity3,Angle,RectCenter_Row,  RectCenter_Column,HomMat2DRotate3)

*因为绕着实际的中心轴做了旋转,mark点的位置发生了变化,可以通过旋转变换得到新的位置

 affine_trans_point_2d(HomMat2DRotate3,ModelRow, ModelCol, Qx, Qy)

实际操作中,告诉手臂旋转角度,以及位移(Row - Qx, Column - Qy)

===============END 第二种==================

扩展--

如果实际贴合的角度与模板的角度不一样,假如其夹角为AngleReal则

vector_angle_to_rigid(modelRow,modelCol,modelAngle+AngleReal,matchRow,matchCol,matchAngle,HomMat2D) 

*下面得到机械手要补偿的数据 

dltRow:=rotateRow-Qx 

dltCol:=rotateCol-Qy 

dltAngle:=matchAngle-modelAngle-AngleReal

机器视觉 视觉 技术干货

好的文章,需要您的鼓励

16

  • 最新资讯
  • 最新问答
推荐