OpenCvSharp 编写CircularCaliper找圆心函数 , 输入图像、找圆扇形区域的最小半径和最大半径、设定扇形区域起始角度、扇形区域结束角度 先剪出找圆扇形区域图像 输入Caliper个数,宽度、长度、 输入从内到外找圆心、从黑到白找圆 中心圆可设定请编写函数
时间: 2023-07-31 22:10:35 浏览: 96
opencv找圆程序
以下是一个使用OpenCvSharp编写的CircularCaliper找圆心函数的示例:
```csharp
public static Point2f FindCircleCenter(Mat image, int minRadius, int maxRadius, double startAngle, double endAngle, int caliperCount, int caliperWidth, int caliperLength, bool searchFromInside, bool searchFromBlackToWhite)
{
// 剪出找圆扇形区域图像
Mat regionOfInterest = new Mat();
Cv2.InRange(image, new Scalar(0), new Scalar(0), regionOfInterest);
Cv2.Ellipse(regionOfInterest, new RotatedRect(new Point2f(image.Width / 2, image.Height / 2), new Size2f(maxRadius, maxRadius), 0), new Scalar(255), -1);
Cv2.Ellipse(regionOfInterest, new RotatedRect(new Point2f(image.Width / 2, image.Height / 2), new Size2f(minRadius, minRadius), 0), new Scalar(0), -1);
Mat regionOfInterestMask = new Mat();
Cv2.InRange(regionOfInterest, new Scalar(1), new Scalar(255), regionOfInterestMask);
Mat regionOfInterestImage = new Mat();
image.CopyTo(regionOfInterestImage, regionOfInterestMask);
// 计算圆弧角度范围
double arcStartAngle = startAngle * Math.PI / 180;
double arcEndAngle = endAngle * Math.PI / 180;
if (arcEndAngle < arcStartAngle)
{
double temp = arcStartAngle;
arcStartAngle = arcEndAngle;
arcEndAngle = temp;
}
// 初始化最小距离和最优圆心
double minDistance = double.MaxValue;
Point2f bestCenter = new Point2f();
// 计算每个刻度线的角度和长度
double angleStep = (arcEndAngle - arcStartAngle) / caliperCount;
int lengthHalf = caliperLength / 2;
// 循环遍历所有刻度线
for (int i = 0; i < caliperCount; i++)
{
// 计算当前刻度线的角度
double angle = arcStartAngle + angleStep * i;
// 计算当前刻度线的起始和结束点
Point2f startPoint = new Point2f((float)(bestCenter.X + minRadius * Math.Cos(angle)), (float)(bestCenter.Y + minRadius * Math.Sin(angle)));
Point2f endPoint = new Point2f((float)(bestCenter.X + maxRadius * Math.Cos(angle)), (float)(bestCenter.Y + maxRadius * Math.Sin(angle)));
// 计算当前刻度线的垂线
Point2f perpendicular = new Point2f((float)Math.Sin(angle), (float)-Math.Cos(angle));
// 初始化当前刻度线的最小距离和最优位置
double minDistanceForCaliper = double.MaxValue;
Point2f bestPositionForCaliper = new Point2f();
// 循环遍历所有位置
for (int j = searchFromInside ? maxRadius : minRadius; searchFromInside ? j >= minRadius : j <= maxRadius; j += searchFromInside ? -1 : 1)
{
// 计算当前位置的坐标
Point2f position = new Point2f((float)(bestCenter.X + j * Math.Cos(angle)), (float)(bestCenter.Y + j * Math.Sin(angle)));
// 计算当前位置的刻度线端点
Point2f caliperStartPoint = new Point2f(position.X - perpendicular.X * lengthHalf, position.Y - perpendicular.Y * lengthHalf);
Point2f caliperEndPoint = new Point2f(position.X + perpendicular.X * lengthHalf, position.Y + perpendicular.Y * lengthHalf);
// 计算当前位置的灰度值
Scalar color = regionOfInterestImage.At<byte>((int)position.Y, (int)position.X);
// 判断是否需要从黑到白或从白到黑查找
if ((searchFromBlackToWhite && color.Val[0] > 128) || (!searchFromBlackToWhite && color.Val[0] < 128))
{
// 计算当前位置的距离
double distance = Math.Abs(caliperWidth - Cv2.PointPolygonTest(new Point2f[] { caliperStartPoint, caliperEndPoint }, new Point2f[] { startPoint, endPoint }, true));
// 更新最小距离和最优位置
if (distance < minDistanceForCaliper)
{
minDistanceForCaliper = distance;
bestPositionForCaliper = position;
}
}
}
// 更新最小距离和最优圆心
if (minDistanceForCaliper < minDistance)
{
minDistance = minDistanceForCaliper;
bestCenter = bestPositionForCaliper;
}
}
// 返回最优圆心
return bestCenter;
}
```
此函数接受输入图像、找圆扇形区域的最小半径和最大半径、设定扇形区域起始角度、扇形区域结束角度、Caliper个数、宽度、长度、输入从内到外找圆心、从黑到白找圆和中心圆可设定等参数,并返回找到的圆心。
阅读全文