OpenCvSharp 编写多线程CircularCaliper找圆心函数 , 输入图像、找圆扇形区域的最小半径和最大半径、设定扇形区域起始角度、扇形区域结束角度 先剪出找圆扇形区域图像 输入Caliper个数,宽度、长度、 输入从内到外找圆心、从黑到白找圆 并行计Caliper区域 中心圆可设定请编写函数
时间: 2023-07-31 17:09:47 浏览: 55
以下是一个使用OpenCvSharp编写的多线程CircularCaliper找圆心函数的示例代码:
```csharp
using System.Threading.Tasks;
using OpenCvSharp;
public static class CircularCaliper
{
public static Point2f FindCenter(Mat input, int minRadius, int maxRadius, float startAngle, float endAngle, int caliperCount, int caliperWidth, int caliperLength, bool searchInsideOut, bool searchBlackToWhite)
{
// Crop circular region of interest
Point2f center = new Point2f(input.Width / 2.0f, input.Height / 2.0f);
Mat mask = new Mat(input.Size(), MatType.CV_8UC1, Scalar.Black);
Cv2.Circle(mask, center, maxRadius, Scalar.White, -1, LineTypes.AntiAlias);
Cv2.Circle(mask, center, minRadius, Scalar.Black, -1, LineTypes.AntiAlias);
Mat roi = new Mat();
Cv2.BitwiseAnd(input, mask, roi);
// Calculate angles for each caliper
float angleStep = (endAngle - startAngle) / (float)caliperCount;
float[] angles = new float[caliperCount];
for (int i = 0; i < caliperCount; i++)
{
angles[i] = startAngle + angleStep * i;
}
// Calculate offsets for each caliper
float[] offsets = new float[caliperCount];
for (int i = 0; i < caliperCount; i++)
{
offsets[i] = (i % 2 == 0) ? caliperWidth / 2.0f : -caliperWidth / 2.0f;
}
// Initialize variables for finding best center
Point2f bestCenter = new Point2f();
double bestScore = double.MaxValue;
// Find center using multiple threads
Parallel.For(0, caliperCount, i =>
{
Point2f caliperCenter = new Point2f(center.X + minRadius * (float)Math.Cos(angles[i]), center.Y + minRadius * (float)Math.Sin(angles[i]));
float caliperLengthCos = caliperLength * (float)Math.Cos(angles[i]);
float caliperLengthSin = caliperLength * (float)Math.Sin(angles[i]);
float searchRadius = (searchInsideOut) ? maxRadius - minRadius : minRadius;
bool foundCenter = false;
double bestCaliperScore = double.MaxValue;
// Search along caliper
for (float j = -searchRadius; j <= searchRadius; j += 0.5f)
{
Point2f caliperPoint1 = new Point2f(caliperCenter.X + j * (float)Math.Sin(angles[i]), caliperCenter.Y - j * (float)Math.Cos(angles[i]));
Point2f caliperPoint2 = new Point2f(caliperPoint1.X + caliperLengthCos, caliperPoint1.Y + caliperLengthSin);
// Check if caliper is inside image
if (caliperPoint1.X >= 0 && caliperPoint1.X < roi.Width && caliperPoint1.Y >= 0 && caliperPoint1.Y < roi.Height &&
caliperPoint2.X >= 0 && caliperPoint2.X < roi.Width && caliperPoint2.Y >= 0 && caliperPoint2.Y < roi.Height)
{
// Extract caliper region
Rect caliperRect = new Rect((int)(caliperPoint1.X - caliperWidth / 2.0f), (int)(caliperPoint1.Y - caliperWidth / 2.0f), caliperWidth, caliperWidth);
Mat caliper = new Mat(roi, caliperRect);
// Calculate score for current position
double score = CalculateScore(caliper, searchBlackToWhite);
// Check if score is better than previous best score
if (score < bestCaliperScore)
{
bestCaliperScore = score;
caliperCenter = new Point2f(caliperPoint1.X + caliperLengthCos / 2.0f, caliperPoint1.Y + caliperLengthSin / 2.0f);
foundCenter = true;
}
}
}
// Update best center if caliper found a better one
if (foundCenter && bestCaliperScore < bestScore)
{
lock (bestCenter)
{
if (bestCaliperScore < bestScore)
{
bestScore = bestCaliperScore;
bestCenter = caliperCenter;
}
}
}
});
return bestCenter;
}
private static double CalculateScore(Mat input, bool searchBlackToWhite)
{
double score = 0.0;
double[] min = new double[1], max = new double[1];
Point2i[] minLoc = new Point2i[1], maxLoc = new Point2i[1];
Cv2.MinMaxLoc(input, out min[0], out max[0], out minLoc[0], out maxLoc[0]);
if (searchBlackToWhite)
{
score = max[0];
}
else
{
score = min[0];
}
return score;
}
}
```
这个函数使用了多线程并行计算每个Caliper的圆心位置,最终返回整个图像的最佳圆心位置。要使用该函数,只需将输入图像、最小和最大半径、起始和结束角度、以及其他参数传递给该函数即可。
相关推荐
![cpp](https://img-home.csdnimg.cn/images/20210720083646.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![xlsx](https://img-home.csdnimg.cn/images/20210720083732.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![pptx](https://img-home.csdnimg.cn/images/20210720083543.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![xlsx](https://img-home.csdnimg.cn/images/20210720083732.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)