c# 0pencvsharp 并行计算图像分块采用卡尺法找直线,找出与水平线夹角小于30度的最佳直线边编写函数输出直线的点
时间: 2024-05-06 08:18:10 浏览: 176
以下是一个使用OpenCVSharp和并行计算的示例代码,可以分块采用卡尺法找直线,并输出与水平线夹角小于30度的最佳直线的点:
```csharp
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using OpenCvSharp;
namespace OpenCVSharp_LineDetection
{
class Program
{
static void Main(string[] args)
{
// 读取图像
var img = Cv2.ImRead("test.jpg", ImreadModes.GrayScale);
// 设置卡尺法的参数
var rho = 1; // 线的距离精度
var theta = Math.PI / 180; // 线的角度精度
var threshold = 100; // 线的最小投票数
var minLength = 100; // 线的最小长度
// 分块处理图像,每块大小为blockSize * blockSize
var blockSize = 100;
var blockList = GetBlockList(img.Width, img.Height, blockSize);
var lines = new List<(Point, Point)>();
Parallel.ForEach(blockList, block =>
{
// 在当前块中找到所有的直线
var linesInBlock = Cv2.HoughLines(img[block.Left:block.Right, block.Top:block.Bottom], rho, theta, threshold, minLength);
// 将直线转换到原始图像坐标系中,并且筛选出与水平线夹角小于30度的直线
foreach (var line in linesInBlock)
{
var pt1 = new Point(line.P1.X + block.Left, line.P1.Y + block.Top);
var pt2 = new Point(line.P2.X + block.Left, line.P2.Y + block.Top);
var angle = GetAngle(pt1, pt2);
if (angle < 30 || angle > 150)
{
lines.Add((pt1, pt2));
}
}
});
// 输出直线的点
foreach (var line in lines)
{
Console.WriteLine($"Line: ({line.Item1.X}, {line.Item1.Y}) - ({line.Item2.X}, {line.Item2.Y})");
}
}
// 计算两点之间的夹角
static double GetAngle(Point pt1, Point pt2)
{
var dx = pt1.X - pt2.X;
var dy = pt1.Y - pt2.Y;
return Math.Atan2(Math.Abs(dy), Math.Abs(dx)) * 180 / Math.PI;
}
// 获取图像分块的列表
static List<Rectangle> GetBlockList(int width, int height, int blockSize)
{
var blockList = new List<Rectangle>();
for (var x = 0; x < width; x += blockSize)
{
for (var y = 0; y < height; y += blockSize)
{
var blockWidth = Math.Min(blockSize, width - x);
var blockHeight = Math.Min(blockSize, height - y);
blockList.Add(new Rectangle(x, y, blockWidth, blockHeight));
}
}
return blockList;
}
}
}
```
在上面的代码中,我们首先读取了一张灰度图像,并设置了卡尺法的参数。然后我们使用`GetBlockList`函数将图像分成大小为`blockSize * blockSize`的块,并使用`Parallel.ForEach`进行并行处理。
在每个块中,我们使用`Cv2.HoughLines`函数找到所有的直线,并将直线转换到原始图像坐标系中。然后我们使用`GetAngle`函数计算每条直线与水平线的夹角,并筛选出夹角小于30度的直线。
最后,我们输出所有符合条件的直线的端点坐标。
阅读全文