opencvsharp 编写canny亚像素找边函数,指定找边方向FindSubPixelEdge
时间: 2023-07-15 07:13:12 浏览: 88
OpenCvSharp边缘检测系列之 Canny算子
以下是使用 OpenCvSharp 实现 Canny 亚像素找边函数,指定找边方向 `FindSubPixelEdge` 的示例代码:
```csharp
using OpenCvSharp;
public static Mat CannySubPixel(Mat src, double threshold1, double threshold2, int apertureSize = 3, bool L2gradient = false)
{
var dst = new Mat();
Cv2.Canny(src, dst, threshold1, threshold2, apertureSize, L2gradient);
var lines = Cv2.HoughLinesP(dst, 1, Math.PI / 180, 50, minLineLength: 50, maxLineGap: 10);
var subPixelEdges = new List<PointF>();
foreach (var line in lines)
{
float dx = line.P2.X - line.P1.X;
float dy = line.P2.Y - line.P1.Y;
float angle = (float)Math.Atan2(dy, dx);
var roi = new Rect((int)line.P1.X, (int)line.P1.Y, (int)(dx + 0.5f), (int)(dy + 0.5f));
var subDst = new Mat(src, roi);
if (angle >= -Math.PI / 4 && angle < Math.PI / 4)
{
Cv2.Transpose(subDst, subDst);
Cv2.Flip(subDst, subDst, FlipMode.Y);
}
else if (angle >= Math.PI / 4 && angle < 3 * Math.PI / 4)
{
Cv2.Flip(subDst, subDst, FlipMode.XY);
}
else if (angle < -Math.PI / 4 && angle >= -3 * Math.PI / 4)
{
Cv2.Transpose(subDst, subDst);
Cv2.Flip(subDst, subDst, FlipMode.X);
}
var subEdges = new Mat();
Cv2.Canny(subDst, subEdges, threshold1, threshold2, apertureSize, L2gradient);
if (subEdges.Rows == 0 || subEdges.Cols == 0)
{
continue;
}
var edgeCount = Cv2.CountNonZero(subEdges);
if (edgeCount <= 2)
{
continue;
}
var subPixelEdge = Cv2.FindSubPixelEdge(subEdges, new Point2f(dx / 2, dy / 2), FindSubPixelEdge.RefineVertical | FindSubPixelEdge.RefineHorizontal);
subPixelEdge.X += roi.X;
subPixelEdge.Y += roi.Y;
subPixelEdges.Add(subPixelEdge);
}
var result = new Mat(src.Size(), MatType.CV_8UC3, Scalar.All(0));
foreach (var edge in subPixelEdges)
{
Cv2.Circle(result, (int)edge.X, (int)edge.Y, 2, Scalar.Red, -1);
}
return result;
}
```
使用方法如下:
```csharp
var src = new Mat("input.jpg", ImreadModes.Grayscale);
var dst = CannySubPixel(src, 50, 150, apertureSize: 3, L2gradient: false);
Cv2.ImShow("Canny SubPixel", dst);
```
其中,`src` 是输入图像,`threshold1` 和 `threshold2` 是 Canny 边缘检测的阈值,`apertureSize` 是 Sobel 算子的大小,`L2gradient` 表示是否使用 L2 范数计算梯度。函数返回的是一个 BGR 格式的图像,其中检测到的亚像素边缘用红色圆圈标出。
阅读全文