含缺损圆中心与半径快速计算

(来点有用的)含缺损圆中心与半径快速计算


by HPC_ZY


有时我们得到的“圆”不圆润,甚至存在缺失。针对这种情况,分享一种好方法。为更好解释算法,所以文中尽量避免使用MATLAB库函数,方便大家转化为C。


一、前面

一些实例

在这里插入图片描述

一些方法

我选择利用边缘进行计算,所以第一步提取图像边缘,方法很多。这里我使用形态学。

im = imsrc-imerode(imsrc,strel('disk',1)); % 原图-腐蚀图
  1. 质心法
    利用平均坐标定位圆心,再计算平均半径。(适用于)
[cx, cy] = find(im>0);	% 找到所有边缘点坐标
center = [sum(x)/length(x),sum(y)/length(y)];	% 计算均值
R = sum(sqrt((x-center(1)).^2+(y-center(2)).^2))/length(x); % 计算半径
  1. 最小二乘法
[x,y] = find(im>0); % 找到所有边缘点坐标
% 计算参数
n=length(x);
xx=x.*x;
yy=y.*y;
xy=x.*y;
% 构造矩阵
A=[sum(x) sum(y) n;sum(xy) sum(yy) sum(y);sum(xx) sum(xy) sum(x)];
B=[-sum(xx+yy);-sum(xx.*y+yy.*y);-sum(xx.*x+xy.*y)];
a=A\B;
% 结果
cx = -0.5*a(1);
cy = -0.5*a(2);
R = sqrt(-(a(3)-cx^2-cy^2));

二、本文方法

原理与实现

  1. 基本原理
    利用圆上“任意弦中垂线经过圆心”+“两不平行线相交于一点”就能确定圆心,如下图(左)。

在这里插入图片描述

  1. 核心算法
    为了计算方便,我们选择更特殊的弦(垂直于两坐标轴的两条弦),这样圆心坐标就如上图(右)所示。计算方法如下:
    步骤一: 任意选择圆内一点Pi(圆外也行,只要保证构造出两条弦);
    步骤二: 过Pi作垂线交圆与a1、a2,作水平线交圆与a3、a4;
    步骤三: 计算Ci坐标。
    当圆为完美圆时,任选一点进行上述操作,就能得到准确的圆心
  2. 统计学优化
    当圆不圆或存在缺陷时,每次得到的Ci都不同,通过统计学删选就能获得较好的圆心位置。具体方法如下:
    步骤一: 利用上述算法获得Ci(疑似圆心)分布图;
    步骤二: 选择适当半径画圈,统计圈内疑似圆心的数量Nj;
    步骤三: 计算Nmax = max(Nj);
    步骤四: 选择满足{Nj | Nj>0.8*nMax}的位置,计算其平均值作为圆心。
    获得圆心以后,也用该方法获取最优半径。
  3. 代码实现
    原理已经描述清楚,大佬们可自行实现,下面只写代码大致结构。
for 
% 1、遍历图像,找到满足行列都存在2个白点(或偶数个)的位置。
% 2、计算它们的平均值作为弦的中点。
% 3、按照上图(右)公式计算疑似圆心,并存储。

for
% 4、统计学删选获取圆心与半径

for
% 5、统计学删选获取半径

实验结果对比

在这里插入图片描述

三、其他

  1. 考虑到部分玩家可能懒得敲代码,或对算法优化方面想交流讨论,把测试代码上传
    (包含上述完整代码,及测试数据)
    代码链接

猜你喜欢

转载自blog.csdn.net/xsz591541060/article/details/105969118
今日推荐