OpenCvSharp 编写多线程CircularCaliper找圆心函数 , 输入图像、找圆弧区域的半径、估计圆弧中心点、设定圆弧域起始角度、圆弧区域结束角度 输入Caliper个数,宽度、长度、 将每个Caliper区域按输入圆弧与半径的交点作小矩形的中心剪出小区域图像 将每个Caliper区域roi内从整体图像中复制成小图像来分析以提高速度,得到的点坐标转换到整体大图的坐标系中 输入从内到外找圆心、从黑到白找圆 输入canny参数 并行计Caliper区域,将Caliper区域所有canny点合并,拟合圆心 输出圆中心点out double centerX, out double centerY,out double Radius请编写函数

时间: 2024-02-03 22:12:02 浏览: 30
以下是使用OpenCvSharp编写多线程CircularCaliper找圆心函数的示例代码: ```csharp using System; using System.Collections.Generic; using System.Threading.Tasks; using OpenCvSharp; public static class CircularCaliper { public static void FindCircleCenter(Mat image, int radius, Point2f center, double startAngle, double endAngle, int numCalipers, int caliperWidth, int caliperLength, out double centerX, out double centerY, out double Radius, bool insideToOutside = true, bool blackToWhite = true, double cannyThreshold1 = 50, double cannyThreshold2 = 150) { // Convert the input image to grayscale Mat grayImage = new Mat(); Cv2.CvtColor(image, grayImage, ColorConversionCodes.BGR2GRAY); // Create a new image to visualize the results Mat resultImage = new Mat(); Cv2.CvtColor(grayImage, resultImage, ColorConversionCodes.GRAY2BGR); // Initialize the output variables centerX = 0; centerY = 0; Radius = 0; // Calculate the angles for each caliper double angleStep = (endAngle - startAngle) / (numCalipers - 1); double[] angles = new double[numCalipers]; for (int i = 0; i < numCalipers; i++) { angles[i] = startAngle + i * angleStep; } // Create a list to hold the points detected by each caliper List<Point>[] caliperPoints = new List<Point>[numCalipers]; for (int i = 0; i < numCalipers; i++) { caliperPoints[i] = new List<Point>(); } // Create a list to hold the ROIs for each caliper Rect[] caliperROIs = new Rect[numCalipers]; // Create a list to hold the small images for each caliper Mat[] caliperImages = new Mat[numCalipers]; // Calculate the start and end angles for the circle double startRadians = startAngle * Math.PI / 180; double endRadians = endAngle * Math.PI / 180; // Calculate the x and y coordinates of the circle center double x = center.X; double y = center.Y; // Create a list to hold the tasks for each caliper List<Task> tasks = new List<Task>(); // Loop through each caliper for (int i = 0; i < numCalipers; i++) { // Calculate the start and end points of the caliper double startX = x + radius * Math.Cos(angles[i] * Math.PI / 180); double startY = y + radius * Math.Sin(angles[i] * Math.PI / 180); double endX = startX + caliperLength * Math.Cos(angles[i] * Math.PI / 180); double endY = startY + caliperLength * Math.Sin(angles[i] * Math.PI / 180); // Calculate the perpendicular line to the caliper double perpAngle = angles[i] + 90; double perpStartX = startX + caliperWidth / 2 * Math.Cos(perpAngle * Math.PI / 180); double perpStartY = startY + caliperWidth / 2 * Math.Sin(perpAngle * Math.PI / 180); double perpEndX = endX + caliperWidth / 2 * Math.Cos(perpAngle * Math.PI / 180); double perpEndY = endY + caliperWidth / 2 * Math.Sin(perpAngle * Math.PI / 180); // Create a new line segment for the caliper LineSegmentPoint caliperLine = new LineSegmentPoint(new Point((int)startX, (int)startY), new Point((int)endX, (int)endY)); // Create a new line segment for the perpendicular line LineSegmentPoint perpLine = new LineSegmentPoint(new Point((int)perpStartX, (int)perpStartY), new Point((int)perpEndX, (int)perpEndY)); // Calculate the intersection points between the two lines Point[] intersections = caliperLine.Intersect(perpLine); // Calculate the ROI for the caliper int roiX = (int)intersections[0].X - caliperWidth / 2; int roiY = (int)intersections[0].Y - caliperWidth / 2; int roiWidth = caliperWidth; int roiHeight = caliperLength + caliperWidth; Rect roi = new Rect(roiX, roiY, roiWidth, roiHeight); // Add the ROI to the list caliperROIs[i] = roi; // Create a new task to process the caliper Task task = Task.Factory.StartNew(() => { // Select the region of interest for the caliper Mat caliperImage = grayImage[roi]; // Create a new image to visualize the results for the caliper Mat caliperResult = new Mat(); Cv2.CvtColor(caliperImage, caliperResult, ColorConversionCodes.GRAY2BGR); // Calculate the Canny edge detector parameters double cannyThresh1 = cannyThreshold1; double cannyThresh2 = cannyThreshold2; // Check if we need to reverse the order of the canny thresholds if (blackToWhite) { cannyThresh1 = cannyThreshold2; cannyThresh2 = cannyThreshold1; } // Detect edges in the caliper region Mat edges = new Mat(); Cv2.Canny(caliperImage, edges, cannyThresh1, cannyThresh2); // Loop through each pixel in the edges image for (int y = 0; y < edges.Rows; y++) { for (int x = 0; x < edges.Cols; x++) { // Check if the pixel is an edge pixel if (edges.At<byte>(y, x) != 0) { // Calculate the coordinates of the pixel in the full image int globalX = roi.X + x; int globalY = roi.Y + y; // Add the point to the list for this caliper caliperPoints[i].Add(new Point(globalX, globalY)); // Draw a circle at the point in the result image Cv2.Circle(caliperResult, new Point(x, y), 1, Scalar.Red, -1); } } } // Add the result for the caliper to the output image caliperResult.CopyTo(resultImage[roi]); // Store the small image for this caliper caliperImages[i] = caliperImage; }); // Add the task to the list tasks.Add(task); } // Wait for all tasks to complete Task.WaitAll(tasks.ToArray()); // Merge the points detected by each caliper List<Point> allPoints = new List<Point>(); for (int i = 0; i < numCalipers; i++) { allPoints.AddRange(caliperPoints[i]); } // Fit a circle to the points Cv2.MinEnclosingCircle(allPoints, out Point2f circleCenter, out float circleRadius); // Update the output variables centerX = circleCenter.X; centerY = circleCenter.Y; Radius = circleRadius; // Draw the circle on the result image Cv2.Circle(resultImage, new Point((int)centerX, (int)centerY), (int)Radius, Scalar.Green, 2); // Show the result image Cv2.ImShow("Result", resultImage); Cv2.WaitKey(); } } ``` 该函数使用了OpenCvSharp的线段类`LineSegmentPoint`和圆拟合函数`Cv2.MinEnclosingCircle`。 要使用该函数,只需将输入图像、圆弧区域的半径、估计圆弧中心点、设定圆弧域起始角度、圆弧区域结束角度、Caliper个数、宽度、长度、内到外或外到内找圆心、从黑到白或白到黑找圆、以及canny参数作为参数传入即可。函数将在多个线程上并行处理每个Caliper区域,并将结果合并以拟合圆心。输出的圆中心点和半径将保存在输出参数`centerX`、`centerY`和`Radius`中。

相关推荐

最新推荐

recommend-type

python多线程接口案例

项目为某内控公司要求并发测试,编写多线程访问接口,并生成Excel报告的脚本,记录基本步骤。 若有需要写UI自动化,接口自动化,多线程,服务器测试定时脚本等等,可联系本工具熊。 分五步操作实现50个或更多用户...
recommend-type

Java多线程之多线程异常捕捉

在java多线程程序中,所有线程都不允许抛出未捕获的checked exception,也就是说各个线程需要自己把自己的checked exception处理掉,通过此篇文章给大家分享Java多线程之多线程异常捕捉,需要的朋友可以参考下
recommend-type

C#多线程处理多个队列数据的方法

主要介绍了C#多线程处理多个队列数据的方法,涉及C#线程与队列的相关操作技巧,需要的朋友可以参考下
recommend-type

Python 多线程+多进程简单使用教程,如何在多进程开多线程

一、Python多进程多线程 关于python多进程多线程的相关基础知识,在我之前的博客有写过,并且就关于python多线程的GIL锁问题,也在我的一篇博客中有相关的解释。 为什么python多线程在面对IO密集型任务的时候会产生...
recommend-type

Python爬虫进阶之多线程爬取数据并保存到数据库

今天刚看完崔大佬的《python3网络爬虫开发实战》,顿时觉得...为了避免这种尴尬,以及我突然想写博客的心情,我决定还是为大家在进行一次简易爬虫展示,总体程序我会利用多线程的方式来充分利用CPU的空闲时间,其中我也
recommend-type

RTL8188FU-Linux-v5.7.4.2-36687.20200602.tar(20765).gz

REALTEK 8188FTV 8188eus 8188etv linux驱动程序稳定版本, 支持AP,STA 以及AP+STA 共存模式。 稳定支持linux4.0以上内核。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

输出删除n个数字,使得被删后的数字最小

对于这个问题,我可以提供一个基于贪心算法的解法。具体来说,我们可以首先遍历一遍数字序列,从左往右找到第一个比它右边的数字大的位置,然后删除这个位置的数字,并重置遍历起点为当前位置。重复这个过程,直到已经删除了n个数字或者数字序列已经被完全遍历。 代码实现如下: ``` def remove_digits(num, n): result = [] for i in range(len(num)): while n > 0 and result and result[-1] > num[i]: result.pop()
recommend-type

c++校园超市商品信息管理系统课程设计说明书(含源代码) (2).pdf

校园超市商品信息管理系统课程设计旨在帮助学生深入理解程序设计的基础知识,同时锻炼他们的实际操作能力。通过设计和实现一个校园超市商品信息管理系统,学生掌握了如何利用计算机科学与技术知识解决实际问题的能力。在课程设计过程中,学生需要对超市商品和销售员的关系进行有效管理,使系统功能更全面、实用,从而提高用户体验和便利性。 学生在课程设计过程中展现了积极的学习态度和纪律,没有缺勤情况,演示过程流畅且作品具有很强的使用价值。设计报告完整详细,展现了对问题的深入思考和解决能力。在答辩环节中,学生能够自信地回答问题,展示出扎实的专业知识和逻辑思维能力。教师对学生的表现予以肯定,认为学生在课程设计中表现出色,值得称赞。 整个课程设计过程包括平时成绩、报告成绩和演示与答辩成绩三个部分,其中平时表现占比20%,报告成绩占比40%,演示与答辩成绩占比40%。通过这三个部分的综合评定,最终为学生总成绩提供参考。总评分以百分制计算,全面评估学生在课程设计中的各项表现,最终为学生提供综合评价和反馈意见。 通过校园超市商品信息管理系统课程设计,学生不仅提升了对程序设计基础知识的理解与应用能力,同时也增强了团队协作和沟通能力。这一过程旨在培养学生综合运用技术解决问题的能力,为其未来的专业发展打下坚实基础。学生在进行校园超市商品信息管理系统课程设计过程中,不仅获得了理论知识的提升,同时也锻炼了实践能力和创新思维,为其未来的职业发展奠定了坚实基础。 校园超市商品信息管理系统课程设计的目的在于促进学生对程序设计基础知识的深入理解与掌握,同时培养学生解决实际问题的能力。通过对系统功能和用户需求的全面考量,学生设计了一个实用、高效的校园超市商品信息管理系统,为用户提供了更便捷、更高效的管理和使用体验。 综上所述,校园超市商品信息管理系统课程设计是一项旨在提升学生综合能力和实践技能的重要教学活动。通过此次设计,学生不仅深化了对程序设计基础知识的理解,还培养了解决实际问题的能力和团队合作精神。这一过程将为学生未来的专业发展提供坚实基础,使其在实际工作中能够胜任更多挑战。