机器人视觉--浅谈单相机贴合
思路:
建模板--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
- 最新资讯
- 最新问答
-
埃斯顿机器人系列有哪些?怎么样?
关键字: 埃斯顿 埃斯顿机器人 系列 2024-07-05 -
轮式机器人的发展及其趋势
关键字: 轮式机器人 发展 趋势 2024-07-03 -
具身智能的定义和作用
关键字: 具身智能 2024-06-28 -
什么是agv小车?特点有哪些?
关键字: agv小车 特点 2024-06-27 -
机器视觉应用的分类?范围有哪些?
关键字: 机器视觉 应用分类 范围 2024-06-25
-
工业机器人技术是干什么的?
标签: 工业机器人,技术 提问:小杰 2024-07-03 13:03:15 -
机器人焊接焊机报TC异常怎么解决
标签: 焊接机器人,焊机,TC异常 提问:TC 2024-06-28 16:05:01 -
机器人运动轨迹的控制方式有哪两种
标签: 机器人,运动轨迹,控制方式 提问:张默 2024-06-25 10:10:02 -
具身智能什么意思
标签: 具身智能,什么意思 提问:MESSE 2024-06-19 10:37:04 -
3D视觉无序抓取系统配置要点?
标签: 3D视觉,无序抓取,系统配置 提问:QUTE 2024-06-17 13:17:05
- 2021-06-10 10:45:45
- 2021-06-11 13:34:28
- 2020-05-29 10:03:22
- 2019-09-24 11:19:01
- 2020-01-16 13:27:13
- 2019-03-22 15:42:15
- 2022-08-05 12:01:03
- 2022-08-30 14:45:07
- 2022-09-08 11:34:03
- 2022-08-12 08:20:38
- 2022-09-21 15:24:58
- 2022-08-03 10:20:40
- 2024-07-05
- 2024-07-03
- 2024-06-28
- 2024-06-27
- 2024-06-25
- 2024-06-20
- 2024-06-19
- 2024-06-17
- 2024-06-13
- 2024-06-11