各种标定+计算定位

移动相机定位(跟着机械手跑,不带旋转轴) 

 9点标定

HTuple Row = new HTuple();//图像row
HTuple Column = new HTuple();//图像column
HTuple X = new HTuple();//机械x
HTuple Y = new HTuple();//机械y
for (int i = 0; i < 9; i++)
{
       Row[i] = Convert.ToDouble(dataGridView3.Rows[i].Cells[0].Value.ToString());
       Column[i] = Convert.ToDouble(dataGridView3.Rows[i].Cells[1].Value.ToString());
       X[i] = Convert.ToDouble(dataGridView3.Rows[8 - i].Cells[2].Value.ToString());
        Y[i] = Convert.ToDouble(dataGridView3.Rows[8 - i].Cells[3].Value.ToString());
}
HOperatorSet.VectorToHomMat2d(Row, Column, Y, X, out homMat2d);
homMat2d: 9点标定矩阵

 计算位置

//获取图像中心对应的  X Y 机械坐标
 HOperatorSet.AffineTransPoint2d(homMat2d, height / 2, width / 2, out Y2, out X2);

HTuple BX, BY;
//获取图像定位的 X Y
HOperatorSet.AffineTransPoint2d(homMat2d, row, column, out BY, out BX);


//定位位置(BX,BY) - 图像中心位置(X2,Y2) = 定位位置到图像中心位置的偏差(X1,Y1)
double X1 = BX.D - X2.D;
double Y1 = BY.D - Y2.D;

//当前机械位置(X3,Y3) + 到图像中心位置的偏差(X1,Y1)
double AX = X3 + X1;
double AY = Y3 + Y1;

(AX,YX):就是最后定位的位置(此位置是图像中心能对准实际定位位置,最后定位的位置)

固定向上相机纠偏(从下往上拍,带旋转角度)

9点标定

HTuple rows = new HTuple(); 
HTuple columns = new HTuple(); 
HTuple robot_x = new HTuple(); 
HTuple robot_y = new HTuple();
for (int i = 0; i < dataGridView_Cam1.Rows.Count-1; i++)
{
  rows [i] = Convert.ToDouble(dataGridView_Cam1.Rows[i].Cells[1].Value.ToString());
  columns [i] = Convert.ToDouble(dataGridView_Cam1.Rows[i].Cells[2].Value.ToString());
  robot_x [i] = Convert.ToDouble(dataGridView_Cam1.Rows[i].Cells[3].Value.ToString());
  robot_y [i] = Convert.ToDouble(dataGridView_Cam1.Rows[i].Cells[4].Value.ToString());
}

HOperatorSet.VectorToHomMat2d(rows , columns , robot_y , robot_x , out homMat2d);

homMat2d:9点标定矩阵

旋转标定

HTuple CenterX = new HTuple();
HTuple CenterY = new HTuple();

HTuple robot_xs= new HTuple();
HTuple robot_ys= new HTuple();


for (int i = 9; i < 22; i++)
{
    HTuple Robot_Point1_X2, Robot_Point1_Y2;
    //将图像旋转的像素坐标转换成机械坐标
    HOperatorSet.AffineTransPoint2d(homMat2d,
    double.Parse(dataGridView_Cam1.Rows[i].Cells[1].Value.ToString()),
    double.Parse(dataGridView_Cam1.Rows[i].Cells[2].Value.ToString()), 
    out Robot_Point1_Y2, out Robot_Point1_X2);
    robot_xs[i - 9] = Robot_Point1_X2.D;
    robot_ys[i - 9] = Robot_Point1_Y2.D;
}
//根基全部变换后的机械坐标  计算旋转中心
Get_Cirrle_Center(robot_xs, robot_ys, out CenterX, out CenterY, halconWindow1);

(CenterX,CenterY):就是圆心(要保存)


//拟合圆心
public void Get_Cirrle_Center(HTuple hv_Rows, HTuple hv_Cols, out HTuple hv_Center_Row, out HTuple hv_Center_Column)
{
     // Local iconic variables 

     HObject ho_Contour, ho_ContCircle, ho_ContCircle1;
     HObject ho_Cross;

     // Local control variables 

     HTuple hv_Radius = new HTuple(), hv_StartPhi = new HTuple();
     HTuple hv_EndPhi = new HTuple(), hv_PointOrder = new HTuple();
     HTuple hv_DistanceMin = new HTuple(), hv_DistanceMax = new HTuple();
     // Initialize local and output iconic variables 
     HOperatorSet.GenEmptyObj(out ho_Contour);
     HOperatorSet.GenEmptyObj(out ho_ContCircle);
     HOperatorSet.GenEmptyObj(out ho_ContCircle1);
     HOperatorSet.GenEmptyObj(out ho_Cross);
     hv_Center_Row = new HTuple();
     hv_Center_Column = new HTuple();
     ho_Contour.Dispose();
     HOperatorSet.GenContourPolygonXld(out ho_Contour, hv_Rows, hv_Cols);

     //拟合一个圆XLD
     hv_Center_Row.Dispose(); hv_Center_Column.Dispose(); hv_Radius.Dispose(); hv_StartPhi.Dispose(); hv_EndPhi.Dispose(); hv_PointOrder.Dispose();
     HOperatorSet.FitCircleContourXld(ho_Contour, "geotukey", -1, 0, 0, 3, 2, out hv_Center_Row, out hv_Center_Column, out hv_Radius, out hv_StartPhi, out hv_EndPhi, out hv_PointOrder);
     //创建圆弧xld
     ho_ContCircle.Dispose();
     HOperatorSet.GenCircleContourXld(out ho_ContCircle, hv_Center_Row, hv_Center_Column, hv_Radius, hv_StartPhi, hv_EndPhi, "negative", 1);
     using (HDevDisposeHelper dh = new HDevDisposeHelper())
     {
         hv_DistanceMin.Dispose(); hv_DistanceMax.Dispose();
         HOperatorSet.DistancePc(ho_ContCircle, hv_Rows.TupleSelect(2), hv_Cols.TupleSelect(2), out hv_DistanceMin, out hv_DistanceMax);
     }
     //判断第三点在不在拟合的弧线上面,这一步主要用点的顺序确定圆弧的其实位置
     if ((int)(new HTuple(hv_DistanceMin.TupleGreater(1))) != 0)
     {
         ho_ContCircle.Dispose();
         HOperatorSet.GenCircleContourXld(out ho_ContCircle, hv_Center_Row, hv_Center_Column, hv_Radius, hv_StartPhi, hv_EndPhi, "positive", 1);
     }
     //拟合一个整圆(其实就是弧度值0到2PI)
     ho_ContCircle1.Dispose();
     HOperatorSet.GenCircleContourXld(out ho_ContCircle1, hv_Center_Row, hv_Center_Column, hv_Radius, 0, 6.28318, "positive", 1);
     using (HDevDisposeHelper dh = new HDevDisposeHelper())
     {
         ho_Cross.Dispose();
         HOperatorSet.GenCrossContourXld(out ho_Cross, hv_Center_Row, hv_Center_Column, hv_Radius / 5, 0);
     }


     ho_Contour.Dispose();
     ho_ContCircle.Dispose();


     hv_Radius.Dispose();
     hv_StartPhi.Dispose();
     hv_EndPhi.Dispose();
     hv_PointOrder.Dispose();
     hv_DistanceMin.Dispose();
     hv_DistanceMax.Dispose();

     return;
 }

基准设定


假设(row_Standar ,col_Standar ,angle_Standar )为产品特征点基准
HTuple row_Standar = new HTuple(0.0);
HTuple col_Standar = new HTuple(0.0);
//这是角度   不是弧度
HTuple angle_Standar = new HTuple(0.0);


//换算后的机械位置
HTuple Robot_x_Standar = new HTuple(0.0);
HTuple Robot_y_Standar = new HTuple(0.0);
HOperatorSet.AffineTransPoint2d(homMat2d, row_Standar , col_Standar , out Robot_y_Standar, out Robot_x_Standar);


//此时(Robot_x_Standar ,Robot_y_Standar ,angle_Standar )为产品基准位置角度

计算偏移量

前面保存的产品基准位置角度(Robot_x_Standar ,Robot_y_Standar ,angle_Standar )


//产品定位的 row,column,angle
HTuple Center_Row = new HTuple(0.00);
HTuple Center_Column = new HTuple(0.00);
HTuple Angle = new HTuple(0.00);//此为角度 不是弧度

HTuple robot_x = new HTuple(0.0);
HTuple robot_y = new HTuple(0.0);


//将定位的(row,column) 转换成机械坐标(robot_x ,robot_y )
HOperatorSet.AffineTransPoint2d(homMat2d, Center_Row, Center_Column, out robot_y, out robot_x);




//极坐标转换
//要转换的角度(基准角度-定位角度)
double rotateR = angle_Standar  - Angle.D;

//极坐标转换后的位置
double robot_Rotate_X = 0, robot_Rotate_Y = 0;
//将定位的位置(机械坐标)旋转中心旋转offsetU 度  得到旋转后的坐标(robot_Rotate_X,robot_Rotate_Y)
Work.RotateAngle(CenterX ,CenterY ,rotateR ,robot_x.D, robot_y.D,                        ref robot_Rotate_X, ref robot_Rotate_Y);

//计算补偿
// xy补偿 (基准位置(Robot_x_Standar ,Robot_y_Standar )-旋转后的位置(robot_Rotate_X,robot_Rotate_Y) = 补偿)

double offsetX = Robot_x_Standar - robot_Rotate_X;
double offsetY = Robot_y_Standar - robot_Rotate_Y;
double offsetr = Angle.D - angle_Standar ;

//最终位置
X = 贴料位置x + offsetX ;
Y = 贴料位置y + offsetY ;
R = 贴料位置r + offsetr ;

贴料位置(可以是死位置   也可以是定位的位置)




//极坐标转换
public static string RotateAngle(double XRotation, double YRotation, double ARotate, double XBefore, double YBefore, ref double XAfter, ref double YAfter)
     {
         try
         {
             double Rad = 0;
             Rad = ARotate * Math.PI / 180;
             XAfter = (XBefore - XRotation) * Math.Cos(Rad) - (YBefore - YRotation) * Math.Sin(Rad) + XRotation;
             YAfter = (XBefore - XRotation) * Math.Sin(Rad) + (YBefore - YRotation) * Math.Cos(Rad) + YRotation;
             return "OK";
         }
         catch (Exception ex)
         {
             return ex.Message;
         }
 }





固定上相机(往下拍 相机固定 带旋转)

9点标定+旋转标定(和固定下相机一样标定)

得到:homMat2d  9点标定矩阵    (CenterX,CenterY):圆心坐标(机械位置)(要保存)

设定基准点 (和固定下相机一样)


假设(row_Standar ,col_Standar ,angle_Standar )为产品特征点基准
HTuple row_Standar = new HTuple(0.0);
HTuple col_Standar = new HTuple(0.0);
//这是角度   不是弧度
HTuple angle_Standar = new HTuple(0.0);


//换算后的机械位置
HTuple Robot_x_Standar = new HTuple(0.0);
HTuple Robot_y_Standar = new HTuple(0.0);
HOperatorSet.AffineTransPoint2d(homMat2d, row_Standar , col_Standar , out Robot_y_Standar, out Robot_x_Standar);


//此时(Robot_x_Standar ,Robot_y_Standar ,angle_Standar )为产品基准位置角度

计算取料位

前面保存的产品基准位置角度(Robot_x_Standar ,Robot_y_Standar ,angle_Standar )


//产品定位的 row,column,angle
HTuple Center_Row = new HTuple(0.00);
HTuple Center_Column = new HTuple(0.00);
HTuple Angle = new HTuple(0.00);//此为角度 不是弧度


 //定位角度
 double location_angle = hv_Angle.TupleDeg().D;
 //定位XY (机械位置)
 HTuple Robot_Point1_X2, Robot_Point1_Y2;
 //将定位的像素换算成机械
 HOperatorSet.AffineTransPoint2d(homMat2d, Row, Column, out Robot_Point1_Y2, out Robot_Point1_X2);
 double location_x = Robot_Point1_Y2.D;
 double location_y = Robot_Point1_X2.D;

 //1 先算出模板的旋转角度   模板角度 - 定位角度 = 角度偏差
 //2 在把模板特征点XY 绕 旋转中心 按照角度偏差旋转  得到新的 X Y
 //3 再用定位的XY - 旋转后的XY  得到新的XY 偏差

 //基准角度 - 定位角度 = 要旋转的角度
 double offsetAngle = angle_Standar  - location_angle;


 double x = 0.0;
 double y = 0.0;

 //将模板基准点饶旋转中心旋转(极坐标转换)
 //固定下相机是旋转定位位置  而这里是旋转设定的基准位置
 RotateAngle(CenterX, CenterY, offsetAngle*-1,Robot_x_Standar ,Robot_y_Standar, ref x, ref y);

 //当前定位(location_x ,location_y) - 旋转后的基准点
 double offsetx = location_x - x;
 double offsety = location_y - y;
 double offsetu = offsetAngle;

 //基准取料机械位置(Standard_X,Standard_Y ,Standard_R ) + 补偿  以实际为准
 double X = Standard_X + offsetx;
 double Y = Standard_Y + offsety;
 double U = Standard_R + offsetu;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值