霍夫峰检测
Hough Peak detection
我已经实现了霍夫峰检测。输出结果如下:
我们可以看到红线与canvas的两侧(左、右)相交。
如何限制源代码行之间检测到的行的长度?
例如,
。
源代码
public class Line
{
public Point Start { get; set; }
public Point End { get; set; }
public Line(Point start, Point end)
{
Start = start;
End = end;
}
}
public class HoughLineTransform
{
public HoughMap Accumulator { get; set; }
public HoughLineTransform()
{
}
public List<Line> GetLines(int threshold)
{
if (Accumulator == null)
{
throw new Exception("HoughMap is null");
}
int houghWidth = Accumulator.Width;
int houghHeight = Accumulator.Height;
int imageWidth = Accumulator.Image.Width;
int imageHeight = Accumulator.Image.Height;
List<Line> lines = new List<Line>();
if (Accumulator == null)
return lines;
for (int rho = 0; rho < houghWidth; rho++)
{
for (int theta = 0; theta < houghHeight; theta++)
{
if ((int)Accumulator[rho, theta] >= threshold)
{
int peak = Accumulator[rho, theta];
for (int ly = -4; ly <= 4; ly++)
{
for (int lx = -4; lx <= 4; lx++)
{
if ((ly + rho >= 0 && ly + rho < houghWidth) && (lx + theta >= 0 && lx + theta < houghHeight))
{
if ((int)Accumulator[rho + ly, theta + lx] > peak)
{
peak = Accumulator[rho + ly, theta + lx];
ly = lx = 5;
}
}
}
}
if (peak > (int)Accumulator[rho, theta])
continue;
int x1, y1, x2, y2;
x1 = y1 = x2 = y2 = 0;
double rad = theta * Math.PI / 180;
if (theta >= 45 && theta <= 135)
{
x1 = 0;
y1 = (int)(((double)(rho - (houghWidth / 2)) - ((x1 - (imageWidth / 2)) * Math.Cos(rad))) / Math.Sin(rad) + (imageHeight / 2));
x2 = imageWidth - 0;
y2 = (int)(((double)(rho - (houghWidth / 2)) - ((x2 - (imageWidth / 2)) * Math.Cos(rad))) / Math.Sin(rad) + (imageHeight / 2));
}
else
{
y1 = 0;
x1 = (int)(((double)(rho - (houghWidth / 2)) - ((y1 - (imageHeight / 2)) * Math.Sin(rad))) / Math.Cos(rad) + (imageWidth / 2));
y2 = imageHeight - 0;
x2 = (int)(((double)(rho - (houghWidth / 2)) - ((y2 - (imageHeight / 2)) * Math.Sin(rad))) / Math.Cos(rad) + (imageWidth / 2));
}
lines.Add(new Line(new Point(x1, y1), new Point(x2, y2)));
}
}
}
return lines;
}
}
Related:
一种简单的方法是在原始图像上叠加生成的 houghlines 并检查像素重叠的位置(具有一定的 window)。
如果它们开始或结束重叠,则您有线段的开始/结束。
顺便说一句:我没有检查过你的算法,但我在大约 15 年前自己写了一个。我记得有一种迭代方法,你一次找到一条线(只是累积图像中的最大值)。
找到一条线后,删除该线的累积像素,然后通过找到最大值重新开始。
然后找到第二重要的行。等等。
我已经实现了霍夫峰检测。输出结果如下:
我们可以看到红线与canvas的两侧(左、右)相交。
如何限制源代码行之间检测到的行的长度?
例如,
。
源代码
public class Line
{
public Point Start { get; set; }
public Point End { get; set; }
public Line(Point start, Point end)
{
Start = start;
End = end;
}
}
public class HoughLineTransform
{
public HoughMap Accumulator { get; set; }
public HoughLineTransform()
{
}
public List<Line> GetLines(int threshold)
{
if (Accumulator == null)
{
throw new Exception("HoughMap is null");
}
int houghWidth = Accumulator.Width;
int houghHeight = Accumulator.Height;
int imageWidth = Accumulator.Image.Width;
int imageHeight = Accumulator.Image.Height;
List<Line> lines = new List<Line>();
if (Accumulator == null)
return lines;
for (int rho = 0; rho < houghWidth; rho++)
{
for (int theta = 0; theta < houghHeight; theta++)
{
if ((int)Accumulator[rho, theta] >= threshold)
{
int peak = Accumulator[rho, theta];
for (int ly = -4; ly <= 4; ly++)
{
for (int lx = -4; lx <= 4; lx++)
{
if ((ly + rho >= 0 && ly + rho < houghWidth) && (lx + theta >= 0 && lx + theta < houghHeight))
{
if ((int)Accumulator[rho + ly, theta + lx] > peak)
{
peak = Accumulator[rho + ly, theta + lx];
ly = lx = 5;
}
}
}
}
if (peak > (int)Accumulator[rho, theta])
continue;
int x1, y1, x2, y2;
x1 = y1 = x2 = y2 = 0;
double rad = theta * Math.PI / 180;
if (theta >= 45 && theta <= 135)
{
x1 = 0;
y1 = (int)(((double)(rho - (houghWidth / 2)) - ((x1 - (imageWidth / 2)) * Math.Cos(rad))) / Math.Sin(rad) + (imageHeight / 2));
x2 = imageWidth - 0;
y2 = (int)(((double)(rho - (houghWidth / 2)) - ((x2 - (imageWidth / 2)) * Math.Cos(rad))) / Math.Sin(rad) + (imageHeight / 2));
}
else
{
y1 = 0;
x1 = (int)(((double)(rho - (houghWidth / 2)) - ((y1 - (imageHeight / 2)) * Math.Sin(rad))) / Math.Cos(rad) + (imageWidth / 2));
y2 = imageHeight - 0;
x2 = (int)(((double)(rho - (houghWidth / 2)) - ((y2 - (imageHeight / 2)) * Math.Sin(rad))) / Math.Cos(rad) + (imageWidth / 2));
}
lines.Add(new Line(new Point(x1, y1), new Point(x2, y2)));
}
}
}
return lines;
}
}
Related:
一种简单的方法是在原始图像上叠加生成的 houghlines 并检查像素重叠的位置(具有一定的 window)。
如果它们开始或结束重叠,则您有线段的开始/结束。
顺便说一句:我没有检查过你的算法,但我在大约 15 年前自己写了一个。我记得有一种迭代方法,你一次找到一条线(只是累积图像中的最大值)。 找到一条线后,删除该线的累积像素,然后通过找到最大值重新开始。 然后找到第二重要的行。等等。