C++ 图像处理——升级版卡尺标定法径向扫描拟合圆(附代码)

C++ 图像处理——升级版卡尺标定法径向扫描拟合圆,附代码

使用语言:C++/Opencv4.3

我针对上一个版本有了一些小改进,不过之前的版本能拟合一个圆环。并对运行速度有了比较大的提升,我先把效果图放上来吧。

在这里插入图片描述
红色的点是我拟定的圆心,绿色的是通过拟合算法得出的圆,绿色的点也是拟合找到的圆心,还有一些参数我在下面介绍。

总体的方法基本不变,还是使用的卡尺的方法。参考的还是Halcon的算子方式。对于参数的设置,看下面:

struct CircleLocConfig
{ 
	cv::Point center;                  //拟合圆心 
	int radius[2] = {0,0};		       //卡尺的半径
	bool  edge_direction  = true;      //边缘方向   False:由黑到白  true:由白到黑
	int selection_of_edge = 0;         //边缘点的选择方式  0:梯度最大  1:第一个满足梯度阈值的点  2:最后一个满足梯度阈值的点
	int edge_threshold = 30;           //边缘阈值:梯度值大于此阈值才能算边缘点
	int starting_angle = 0;	           //起始角
	int termination_angle = 360;       //终止角
	int angle_step;                    //角度步长(径向扫描采样数量)
};

可以通过这么些参数来设置,相当于设置一个ROI区域一样,来选择这么拟合圆。向上面的那个效果图,就是将红色的点设为ROI区域的圆心,然后将卡尺的头端和尾端设置到合适的长度就行了,至于边缘方向那些,我就是设置的第一个梯度点、从白到黑的梯度,起始角为0,终止角度为360,步长是360,相当于每一度就设置一个卡尺。

大概示意图是这样的:

请添加图片描述

灰色的就是卡尺,相当于ROI。
好像蛮丑的。哈哈哈。

请添加图片描述
请添加图片描述
请添加图片描述
代码是原创,进行了封装,注释我也尽可能打全了,会提供.cpp和.h 文件,花了几天才敲出来,收个几块钱混口饭吃,希望大家多多包涵。(●’◡’●)


链接: https://download.csdn.net/download/qq_40374812/20603810.


请添加图片描述

请添加图片描述

请添加图片描述

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
以下是使用最小二乘拟合C++代码: ```cpp #include <iostream> #include <vector> #include <cmath> // 定义点的结构体 struct Point { double x; double y; }; // 定义的结构体 struct Circle { double x; double y; double r; }; // 求解的函数 Circle calcCircle(std::vector<Point>& points) { int n = points.size(); // 计算点集的中心坐标 double sumX = 0.0, sumY = 0.0; for (int i = 0; i < n; ++i) { sumX += points[i].x; sumY += points[i].y; } double centerX = sumX / n; double centerY = sumY / n; // 计算协方差矩阵 double Sxx = 0.0, Syy = 0.0, Sxy = 0.0, Sxxx = 0.0, Sxxy = 0.0, Sxyy = 0.0, Syyy = 0.0; for (int i = 0; i < n; ++i) { double xi = points[i].x - centerX; double yi = points[i].y - centerY; Sxx += xi * xi; Syy += yi * yi; Sxy += xi * yi; Sxxx += xi * xi * xi; Sxxy += xi * xi * yi; Sxyy += xi * yi * yi; Syyy += yi * yi * yi; } double C1 = Sxx + Syy; double C2 = Sxx * Syy - Sxy * Sxy; double C3 = Sxxx + Sxxy; double C4 = Sxxy + Sxyy; double C5 = Syyy - Syy * Sxx; // 求解的参数 double a = (C4 * C2 - C5 * Sxy) / (C3 * C3 - C2 * C4); double b = (C5 * C3 - C4 * C4) / (C3 * C3 - C2 * C4); double c = -(a * centerX + b * centerY + C1) / n; // 计算心和半径 double circleX = -a / 2.0; double circleY = -b / 2.0; double radius = std::sqrt(circleX * circleX + circleY * circleY - c); return {circleX + centerX, circleY + centerY, radius}; } int main() { // 创建点集 std::vector<Point> points = {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}}; // 求解 Circle circle = calcCircle(points); // 输出的参数 std::cout << "centerX: " << circle.x << "\n"; std::cout << "centerY: " << circle.y << "\n"; std::cout << "radius: " << circle.r << "\n"; return 0; } ``` 该程序使用了最小二乘求解的参数,并且输入为一个点集,输出为的中心坐标和半径。可以根据需要修改程序以适应不同的输入格式和输出格式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fire丶Chicken

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值