原理:原理部分网上大部分可以搜得到,以一句很简单的话就是是通过最小化误差的平方和找到一组数据的最佳函数匹配(自行百度)。
作用:如果现在有一张图片,需要你拟合图片中的圆。
需要拟合的圆图片:
方法:最小二乘法拟合(原理自行百度)
代码:主代码
clear;
clc;
data=imread('')
[t,SM]=graythresh(data);% T产生的阈值,SM可分性度量
binary_image=imbinarize(data,t); % Otsu's方法的最佳全阈值处 理,二值化图像
binary_image1=medfilt2(binary_image);
im_sub = double(binary_image);
[m,n]=size(im_sub);
im_sub1=edge(im_sub,'canny',t);
bound_position = bwboundaries(im_sub1,8);
Xc = size(im_sub2,2)/2;Yc = size(im_sub2,1)/2;
result = [];
for i = 1:length(bound_position)
X = bound_position{i}(:,2);Y = bound_position{i}(:,1);
%% 排除掉非轮廓数据
if(length(X)<4)
continue;
end
[xc,yc,r,a] = circlefit(X,Y);%拟合圆
%% 排除掉非圆的轮廓
% if(~inpolygon(xc,yc,X,Y)||r>350||(sqrt((xc-960)^2+(yc-960)^2)>200))
if(~inpolygon(xc,yc,X,Y)||(sqrt((xc-m/2)^2+(yc-n/2)^2)>500)||r>1200);
continue;
end
if r<20
continue;
end
result = [result; xc,yc,r];%保存结果
end
temp= sortrows(result,3);%按半径大小排列
result = temp(1:1:end,:);
for i = 1:1:size(dis_x1,1)
%PlotCircle(result(i,1),result(i,2),mean(result(i-1:i,3)));hold on;
PlotCircle(dis_x1(i,1),dis_x1(i,2),dis_x1(i,3));hold on;
end
disp('-------------拟合结果如下------------')
disp(' 圆心坐标x 圆心坐标y 半径r')
ans = result(1:2:end,:)
以上就通过一些简单的图像处理得到图中圆形图案的边缘坐标信息,下面通过上述的代码获得的边缘像素坐标集,上述中的圆拟合代码如下(最小二乘法)
圆拟合代码:
function [xc,yc,R,a]=circlefit(x,y)
% CIRCLEFIT fits a circle in x,y plane
% x^2+y^2+a(1)*x+a(2)*y+a(3)=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;
xc = -0.5*a(1);
yc = -0.5*a(2);
% R = sqrt(-(a(3)-xc^2-yc^2));
R = sqrt((a(1)^2+a(2)^2)/4-a(3));
end
画圆程序:
function PlotCircle(xc,yc,r)
theta=0:pi/100:2*pi;
% x=r*cos(theta)+xc; y=r*sin(theta)+yc;
x=r*cos(theta)+xc; y=r*sin(theta)+yc;
plot(x,y,'r-','LineWidth',3);
% plot(xc,yc,'r+','LineWidth',5);
% plot(mean(xc),mean(yc),'*','LineWidth',1)
% fill(x,y,'y');
end
效果:
引用请注明出处,谢谢!!
文章出处登录后可见!
已经登录?立即刷新