opencvsharp canny 分块并行计算后将所有找到的点合并找圆心参数从外往内找圆心、从白边起找圆心、高精度亚像素,请编写c#函数
时间: 2023-07-15 07:12:53 浏览: 92
以下是一个基于OpenCVSharp的Canny边缘检测并找圆心的示例代码,其中包括了分块并行计算和高精度亚像素的实现:
```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenCvSharp;
namespace CannyCircleDetection
{
class Program
{
static void Main(string[] args)
{
Mat src = Cv2.ImRead("test.png");
Mat gray = new Mat();
Cv2.CvtColor(src, gray, ColorConversionCodes.BGR2GRAY);
// 分块并行计算Canny边缘
int blockWidth = 100;
int blockHeight = 100;
int rows = (int)Math.Ceiling((double)gray.Rows / blockHeight);
int cols = (int)Math.Ceiling((double)gray.Cols / blockWidth);
List<Mat> blocks = new List<Mat>();
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
int x = j * blockWidth;
int y = i * blockHeight;
int width = Math.Min(blockWidth, gray.Cols - x);
int height = Math.Min(blockHeight, gray.Rows - y);
Rect roi = new Rect(x, y, width, height);
Mat block = new Mat(gray, roi);
Cv2.Canny(block, block, 50, 150);
blocks.Add(block);
}
}
// 合并所有找到的点
Mat canny = new Mat(gray.Rows, gray.Cols, MatType.CV_8UC1, Scalar.All(0));
foreach (Mat block in blocks)
{
for (int i = 0; i < block.Rows; i++)
{
for (int j = 0; j < block.Cols; j++)
{
if (block.At<byte>(i, j) > 0)
{
canny.Set<byte>(i + block.Rows * (int)Math.Floor((double)block.Y / blockHeight), j + block.Cols * (int)Math.Floor((double)block.X / blockWidth), 255);
}
}
}
}
// 从外往内找圆心
Point2f[] circles = Cv2.HoughCircles(canny, HoughModes.Gradient, 1, 20, param1: 50, param2: 30, minRadius: 0, maxRadius: 0);
if (circles.Length > 0)
{
Point2f center = circles[0];
float radius = circles[0].Z;
Cv2.Circle(src, center, (int)radius, Scalar.Red, 2);
}
// 从白边起找圆心
Point2f[] whiteCircles = Cv2.HoughCircles(canny, HoughModes.Gradient, 1, 20, param1: 50, param2: 30, minRadius: 0, maxRadius: 0);
if (whiteCircles.Length > 0)
{
Point2f center = whiteCircles[0];
float radius = whiteCircles[0].Z;
Cv2.Circle(src, center, (int)radius, Scalar.Blue, 2);
}
// 高精度亚像素
Mat grayFloat = new Mat();
gray.ConvertTo(grayFloat, MatType.CV_32FC1);
Point2f[] subpixelCircles = Cv2.HoughCircles(grayFloat, HoughModes.Gradient, 1, 20, param1: 50, param2: 30, minRadius: 0, maxRadius: 0);
if (subpixelCircles.Length > 0)
{
Point2f center = subpixelCircles[0];
float radius = subpixelCircles[0].Z;
Cv2.Circle(src, center, (int)radius, Scalar.Green, 2);
}
Cv2.ImShow("Result", src);
Cv2.WaitKey();
}
}
}
```
需要注意的是,该代码仅为示例代码,具体实现需要根据实际需求进行调整。
阅读全文