` [DisplayName(“滤波高值”)]
public int ThresholdHight { get; set; } = 24;
[DisplayName(“滤波低值”)]
public int ThresholdLow { get; set; } = 24;
[DisplayName(“十字线宽”)]
public int CrossLineWidth { get; set; } = 60;
[DisplayName("是否显示轮廓")]
public YesNo ShowOutline { get; set; } = true;
[DisplayName("第一次过滤最短线长")]
public int FristSelectLineShort { get; set; } = 255;
[DisplayName("是否显示第一次过滤线长")]
public YesNo ShowFristSelectXLD { get; set; } = true;
[DisplayName("第二次过滤最短线长")]
public int DoubleSelectLineShort { get; set; } = 500;
[DisplayName("是否显示第二次过滤线长")]
public YesNo ShowDoubleSelectXLD { get; set; } = true;
public bool FindCross(out HObject contours)
{
if (!base.Execute())
{
contours = null;
return false;
}
if (ImageProvider == null || !ImageProvider.Enabled || !ImageProvider.GetResult())
{
contours = null;
return false;
}
// Initialize local and output iconic variables
HOperatorSet.GenEmptyObj(out HObject ho_Angio);
HOperatorSet.GenEmptyObj(out HObject ho_GrayImage);
HOperatorSet.GenEmptyObj(out HObject ho_Lines);
HOperatorSet.GenEmptyObj(out HObject ho_RelLines);
HOperatorSet.GenEmptyObj(out HObject ho_UnionContours);
HOperatorSet.GenEmptyObj(out HObject ho_asd);
HObject curImage = ImageProvider.GetCurrentImage();
HOperatorSet.Rgb1ToGray(ho_Angio, out ho_GrayImage);
//根据最大线宽和对比度计算lines_gauss的三个参数
//第1个参数:最大线宽
//第2个参数:对比度,若有2个值,第2个值为最小对比度且一定小于第1个值;若
//仅有1个值,则最小对比度为最大对比度的1/3
calculate_lines_gauss_parameters(CrossLineWidth, (new HTuple(ThresholdHight)).TupleConcat(ThresholdLow), out HTuple hv_Sigma,
out HTuple hv_Low, out HTuple hv_High);
//计算高斯直线
ho_Lines.Dispose();
HOperatorSet.LinesGauss(curImage, out ho_Lines, hv_Sigma, hv_Low, hv_High,
"dark", "true", "parabolic", "true");
//过滤固定线长的轮廓
ho_RelLines.Dispose();
HOperatorSet.SelectContoursXld(ho_Lines, out ho_RelLines, "length", FristSelectLineShort, 9999, 0, 0);
if (ShowFristSelectXLD)
{
contours = ho_RelLines;
Owner.Display.ShowObject(ho_RelLines);
}
//将共线的轮廓连接起来
ho_UnionContours.Dispose();
HOperatorSet.UnionCollinearContoursXld(ho_RelLines, out ho_UnionContours, 1000, 1, 6, 0.1, "attr_keep");
//过滤固定线长的轮廓
ho_asd.Dispose();
HOperatorSet.SelectContoursXld(ho_UnionContours, out ho_asd, "length", DoubleSelectLineShort, 9999, 0, 0);
if (ShowDoubleSelectXLD)
{contours = ho_RelLines;
Owner.Display.ShowObject(ho_asd);
}
//拟合直线
HOperatorSet.FitLineContourXld(ho_asd, "tukey", -1, 0, 5, 2, out HTuple hv_RowBegin,
out HTuple hv_ColBegin, out HTuple hv_RowEnd, out HTuple hv_ColEnd, out HTuple hv_Nr, out HTuple hv_Nc, out HTuple hv_Dist);
HOperatorSet.TupleLength(hv_ColBegin, out HTuple length);
if (length != 2)//避免取到过多直线
{
contours = null;
return false;
}
else
{
contours = ho_RelLines;
}
List<PointF> Points = new List<PointF>();
for (int i = 0; i < 2; i++)
{
double ox1 = 0, oy1 = 0, ox2 = 0, oy3 = 0;
imageProvider.ConvertXY(hv_ColBegin[i], hv_RowBegin[i], ref ox1, ref oy1);
imageProvider.ConvertXY(hv_ColEnd[i], hv_RowEnd[i], ref ox2, ref oy3);
PointF point = new PointF((float)ox1, (float)oy1);
PointF point1 = new PointF((float)ox2, (float)oy3);
Points.Add(point);
Points.Add(point1);
}
PointF CrossPoint = GetIntersection(Points[0], Points[1], Points[2], Points[3]);
SetRunDataDouble("Xstart1", Points[0].X);
SetRunDataDouble("Ystart1", Points[0].Y);
SetRunDataDouble("XEmd1", Points[1].X);
SetRunDataDouble("YEmd1", Points[1].Y);
SetRunDataDouble("Xstart2", Points[2].X);
SetRunDataDouble("Ystart2", Points[2].Y);
SetRunDataDouble("XEmd2", Points[3].X);
SetRunDataDouble("YEmd2", Points[3].Y);
SetRunDataDouble("X", CrossPoint.X);
SetRunDataDouble("Y", CrossPoint.Y);
if (ShowOutline)
{
Line l1 = new Line(hv_ColBegin[0], hv_RowBegin[0], hv_ColEnd[0], hv_RowEnd[0]);
Line l2 = new Line(hv_ColBegin[1], hv_RowBegin[1], hv_ColEnd[1], hv_RowEnd[1]);
//Line l1 = new Line(Points[0].X, Points[0].Y, Points[1].X, Points[1].Y);
//Line l2 = new Line(Points[2].X, Points[2].Y, Points[3].X, Points[3].Y);
Owner.Display.ShowLine(l1, "green", 1, 0.2);
Owner.Display.ShowLine(l2, "green", 1, 0.2);
//Owner.Display.ShowObject(ho_asd);
}
return true;
}
protected override bool Execute()
{
return FindCross(out HObject contours);
}`
算法的重点在于高斯直线的拟合,过滤小线段,连接相临线段,过滤连接后的线,然后拟合线。
连接后的过滤可以过滤全部的小线段。

本文介绍了Halcon中的十字线抓取算法,关键在于滤波阈值设定和线段处理。通过设置滤波高值和低值为24,以及十字线宽度为60,算法能有效拟合高斯直线,过滤掉小线段,并连接相邻线段。最终,对连接后的线进行过滤和拟合,实现精准的十字线检测。
4861

被折叠的 条评论
为什么被折叠?



