1.前言
1.1什么是平行度
平行度指两平面或者两直线平行的程度,指一平面(边)相对于另一平面(边)平行的误差最大允许值。
平行度评价直线之间、平面之间或直线与平面之间的平行状态。其中一个直线或平面是评价基准,而直线可以是被测样品的直线部分或直线运动轨迹,平面可以是被测样品的平面部分或运动轨迹形成的平面。
1.2平行度评价方式
测量线对线平行度误差
公差要求是测量孔的轴线相对于基准孔的轴线的平行度误差。需要用心轴模拟被测要素和基准要素,将两根心轴装于基准孔和被测孔内,形成稳定接触,
1.3halcon实现方式
针对线线平行度的评价标准,所以预先定义直线1作为基准线,直线2作为被测线。对直线2上的2个端点对基准线计算距离,并求2个距离的差值,差值的数额即为平行度的误差
2.程序
2.1C#和halcon程序
#region // 计算平行度(直线1的2个端点,到直线2的距离,的差值)
public static bool parallel(HObject Image, bool FastSet,
HTuple ROIBeginRow1, HTuple ROIBeginCloumn1, HTuple ROIEndRow1, HTuple ROIEndCloumn1,
HTuple ROIBeginRow2, HTuple ROIBeginCloumn2, HTuple ROIEndRow2, HTuple ROIEndCloumn2,
out HObject lineContours1, out HTuple resultRowBegin1,
out HTuple resultColumnBegin1, out HTuple resultRowEnd1, out HTuple resultCloumnEnd1,
out HObject lineContours2, out HTuple resultRowBegin2,
out HTuple resultColumnBegin2, out HTuple resultRowEnd2, out HTuple resultCloumnEnd2,
out double Distance)
{
Distance = -1;
HOperatorSet.GenEmptyObj(out lineContours1);
HOperatorSet.GenEmptyObj(out lineContours2);
resultRowBegin1 = -1;
resultColumnBegin1 = -1;
resultRowEnd1 = -1;
resultCloumnEnd1 = -1;
resultColumnBegin2 = -1;
resultRowBegin2 = -1;
resultRowEnd2 = -1;
resultCloumnEnd2 = -1;
try
{
bool line1 = false, line2 = false;
if (FastSet)
{
line1 = Module.LineMeasure_(Image, ROIBeginRow1, ROIBeginCloumn1, ROIEndRow1, ROIEndCloumn1,
30, 5, 2, 20, "uniform", "first", out lineContours1, out resultRowBegin1,
out resultColumnBegin1, out resultRowEnd1, out resultCloumnEnd1);
line2 = Module.LineMeasure_(Image, ROIBeginRow2, ROIBeginCloumn2, ROIEndRow2, ROIEndCloumn2,
30, 5, 2, 20, "uniform", "first", out lineContours2, out resultRowBegin2,
out resultColumnBegin2, out resultRowEnd2, out resultCloumnEnd2);
if (!line1 || !line2)
{
return false;
}
HOperatorSet.DistancePl(resultRowBegin1, resultColumnBegin1, resultRowBegin2, resultColumnBegin2,
resultRowEnd2, resultCloumnEnd2, out HTuple distance1);
HOperatorSet.DistancePl(resultRowEnd1, resultCloumnEnd1, resultRowBegin2, resultColumnBegin2,
resultRowEnd2, resultCloumnEnd2, out HTuple distance2);
double d1= distance1,d2= distance2;
Distance = Math.Abs(d1 - d2);
}
return true;
}
catch (Exception)
{
return false;
}
}
#endregion
#region // 直线查找
/// <summary>
/// 直线查找
/// </summary>
/// <param name="image">输入图像</param>
/// <param name="BeginRow">输入ROI的开始横坐标</param>
/// <param name="EndRow">输入ROI的结束横坐标</param>
/// <param name="BeginColumn">输入ROI开始列坐标</param>
/// <param name="EndColumn">输入ROI的结束列坐标</param>
/// <param name="MeasureHeight">输入测量矩形高度</param>
/// <param name="MeasureWide">输入测量矩形宽度</param>
/// <param name="Sigma">输入测量矩形的高斯滤波值</param>
/// <param name="Threshold">输入最小边缘对比度</param>
/// <param name="Measure_Set">选择拟合边1(“uniform”:最接近ROI轮廓的拟合边;“positive”:由亮到暗,“negative”:由暗到亮)</param>
/// <param name="Measure_Place">选择拟合边2(“first”:所有轮廓的第一条边,“last”:所有轮廓的最后一个边,“all”:最接近ROI轮廓的拟合边)</param>
/// <param name="LineContours">结果轮廓</param>
/// <param name="ResultRowBegin">结果轮廓开始横坐标</param>
/// <param name="ResultRowEnd">结果轮廓结束横坐标</param>
/// <param name="ResultColumnBegin">结果轮廓开始列坐标</param>
/// <param name="ResultCloumnEnd">结果轮廓结束列坐标</param>
/// <returns>拟合成功返回true,拟合失败返回false</returns>
static public bool LineMeasure_(HObject image, HTuple BeginRow, HTuple BeginColumn, HTuple EndRow,
HTuple EndColumn, HTuple MeasureHeight, HTuple MeasureWide, HTuple Sigma, HTuple Threshold,
HTuple Measure_Set, HTuple Measure_Place, out HObject LineContours,
out HTuple ResultRowBegin, out HTuple ResultColumnBegin, out HTuple ResultRowEnd,
out HTuple ResultCloumnEnd)
{
HOperatorSet.GenEmptyObj(out LineContours);
ResultRowBegin = null;
ResultColumnBegin = null;
ResultCloumnEnd = null;
ResultRowEnd = null;
try
{
HOperatorSet.CreateMetrologyModel(out HTuple metrologyHandle);
HOperatorSet.AddMetrologyObjectLineMeasure(metrologyHandle, BeginRow, BeginColumn, EndRow, EndColumn,
MeasureHeight, MeasureWide, Sigma, Threshold, new HTuple(), new HTuple(), out HTuple index);
HOperatorSet.SetMetrologyObjectParam(metrologyHandle, new HTuple("all"), (new HTuple("measure_transition")
).TupleConcat("measure_select"), (new HTuple(Measure_Set)
).TupleConcat(Measure_Place));
//HOperatorSet.SetMetrologyObjectParam(metrologyHandle, new HTuple("all"), new HTuple("min_score"), 0.1);
HOperatorSet.ApplyMetrologyModel(image, metrologyHandle);
HOperatorSet.GetMetrologyObjectResultContour(out LineContours, metrologyHandle, new HTuple("all"), new HTuple("all")
, new HTuple(1.5));
HOperatorSet.GetMetrologyObjectResult(metrologyHandle, index, new HTuple("all"), new HTuple("result_type"),
new HTuple("row_begin"), out ResultRowBegin);
HOperatorSet.GetMetrologyObjectResult(metrologyHandle, index, new HTuple("all"), new HTuple("result_type"),
new HTuple("row_end"), out ResultRowEnd);
HOperatorSet.GetMetrologyObjectResult(metrologyHandle, index, new HTuple("all"), new HTuple("result_type"),
new HTuple("column_begin"), out ResultColumnBegin);
HOperatorSet.GetMetrologyObjectResult(metrologyHandle, index, new HTuple("all"), new HTuple("result_type"),
new HTuple("column_end"), out ResultCloumnEnd);
HOperatorSet.TupleLength(ResultRowBegin, out HTuple length);
if (length == 0)
{
return false;
}
return true;
}
catch (Exception ex)
{
return false;
}
}
#endregion
2.2程序讲解
2.2.1读取图像和绘制ROI,并拟合直线
line1 = Module.LineMeasure_(Image, ROIBeginRow1, ROIBeginCloumn1, ROIEndRow1, ROIEndCloumn1,
30, 5, 2, 20, "uniform", "first", out lineContours1, out resultRowBegin1,
out resultColumnBegin1, out resultRowEnd1, out resultCloumnEnd1);
line2 = Module.LineMeasure_(Image, ROIBeginRow2, ROIBeginCloumn2, ROIEndRow2, ROIEndCloumn2,
30, 5, 2, 20, "uniform", "first", out lineContours2, out resultRowBegin2,
out resultColumnBegin2, out resultRowEnd2, out resultCloumnEnd2);
2.2.计算平行度
HOperatorSet.DistancePl(resultRowBegin1, resultColumnBegin1, resultRowBegin2, resultColumnBegin2,
resultRowEnd2, resultCloumnEnd2, out HTuple distance1);
HOperatorSet.DistancePl(resultRowEnd1, resultCloumnEnd1, resultRowBegin2, resultColumnBegin2,
resultRowEnd2, resultCloumnEnd2, out HTuple distance2);
double d1= distance1,d2= distance2;
Distance = Math.Abs(d1 - d2);
总结
由于2D检测中并不适配面测量,所以文中仅设定线线平行度。当计算平行度误差过大是,可能出现直线的直线度过大造成的误差。