图像处理如何进行直线拟合

2018-06-13 12:56:20 ma7856728 阅读数 8808

在边缘检测中总会提取出不连续点,或伪轮廓。在这种情况下需要拟合出目标的轮廓,这样可以找到轮廓的数学表达式为后续的特征选取打下基础。博主用coins图像为例,用椭圆方程进行拟合,做出如下实验。

1、原图二值化

2、边缘检测(sobel算子)

3、填补孔洞

4、标记连通域

5、找到每个连通域坐标

6、用每个连通域坐标拟合出椭圆方程

7、在二值图像中画出每个椭圆函数

%%图像边缘检测和拟合轮廓
clc
clear
close all
%% 读取图像
I = imread('coins.png');
I = im2bw(I);                                   %二值化
I = imfill(I,'holes');                          %填补孔洞
[M,N] = size(I);
figure(1),imshow(I);title('原图');hold on
%% 选取待拟合坐标
% conicP = ginput(15);            
bw1 = edge(I,'sobel');                           %边缘检测
figure(2),imshow(bw1);title('边缘检测');
[L,num] = bwlabel(bw1);                           %标签
for i = 1:num
    [row,col] = find(L == i);
    conicP = zeros(length(row),2);
    conicP(:,1) = col;
    conicP(:,2) = row;
    figure(1),plot(conicP(:,1)', conicP(:,2)', 'xr');     %drawing sample points
%% 自定义椭圆函数拟合
    a0 = [1 1 1 1 1 1];
    f = @(a,x)a(1)*x(:,1).^2+a(2)*x(:,2).^2+a(3)*x(:,1).*x(:,2)+a(4)*x(:,1)+a(5)*x(:,2)+a(6);%建立方程
    p = nlinfit(conicP , zeros(size(conicP, 1), 1), f,[1 2 3 4 5 6]);
    syms x y
    conic = p(1)*x^2+p(2)*y^2+p(3)*x*y+p(4)*x+p(5)*y+p(6);
%% 在原图上显示拟合结果
    c = ezplot(conic,[0,N],[0,M]);
    figure(1),set(c, 'Color', 'Blue','LineWidth',2);
   
end
 hold off

实验结果图像如下,拟合结果为蓝线,原坐标为红点


2012-06-22 21:24:50 abcjennifer 阅读数 189297

使用Matlab进行拟合是图像处理中线条变换的一个重点内容,本文将详解Matlab中的直线拟合和曲线拟合用法。

关键函数:

fittype

Fit type for curve and surface fitting

Syntax

ffun = fittype(libname)
ffun = fittype(expr)
ffun = fittype({expr1,...,exprn})
ffun = fittype(expr, Name, Value,...)
ffun= fittype({expr1,...,exprn}, Name, Value,...)

/***********************************线性拟合***********************************/

线性拟合公式:

coeff1 * term1 + coeff2 * term2 + coeff3 * term3 + ...
其中,coefficient是系数,term都是x的一次项。

线性拟合Example:

Example1: y=kx+b;

法1:

x=[1,1.5,2,2.5,3];y=[0.9,1.7,2.2,2.6,3];
p=polyfit(x,y,1);
x1=linspace(min(x),max(x));
y1=polyval(p,x1);
plot(x,y,'*',x1,y1);
结果:p =    1.0200    0.0400

即y=1.0200 *x+ 0.0400

法2:

x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];
p=fittype('poly1')
f=fit(x,y,p)
plot(f,x,y);
运行结果:

 x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];
p=fittype('poly1')
f=fit(x,y,p)
plot(f,x,y);

p = 

     Linear model Poly1:
     p(p1,p2,x) = p1*x + p2

f = 

     Linear model Poly1:
     f(x) = p1*x + p2
     Coefficients (with 95% confidence bounds):
       p1 =        1.02  (0.7192, 1.321)
       p2 =        0.04  (-0.5981, 0.6781)

Example2:y=a*x + b*sin(x) + c

法1:

x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];
EXPR = {'x','sin(x)','1'};
p=fittype(EXPR)
f=fit(x,y,p)
plot(f,x,y);

运行结果:

 x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];
EXPR = {'x','sin(x)','1'};
p=fittype(EXPR)
f=fit(x,y,p)
plot(f,x,y);

p = 

     Linear model:
     p(a,b,c,x) = a*x + b*sin(x) + c

f = 

     Linear model:
     f(x) = a*x + b*sin(x) + c
     Coefficients (with 95% confidence bounds):
       a =       1.249  (0.9856, 1.512)
       b =      0.6357  (0.03185, 1.24)
       c =     -0.8611  (-1.773, 0.05094)

法2:
x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];
 p=fittype('a*x+b*sin(x)+c','independent','x')
f=fit(x,y,p)
plot(f,x,y);
运行结果:
x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];
 p=fittype('a*x+b*sin(x)+c','independent','x')
f=fit(x,y,p)
plot(f,x,y);

p = 

     General model:
     p(a,b,c,x) = a*x+b*sin(x)+c
Warning: Start point not provided, choosing random start
point. 
> In fit>iCreateWarningFunction/nThrowWarning at 738
  In fit>iFit at 320
  In fit at 109 

f = 

     General model:
     f(x) = a*x+b*sin(x)+c
     Coefficients (with 95% confidence bounds):
       a =       1.249  (0.9856, 1.512)
       b =      0.6357  (0.03185, 1.24)
       c =     -0.8611  (-1.773, 0.05094)


/***********************************非线性拟合***********************************/

Example:y=a*x^2+b*x+c

法1:

x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];
 p=fittype('a*x.^2+b*x+c','independent','x')
f=fit(x,y,p)
plot(f,x,y);

运行结果:

p = 

     General model:
     p(a,b,c,x) = a*x.^2+b*x+c
Warning: Start point not provided, choosing random start
point. 
> In fit>iCreateWarningFunction/nThrowWarning at 738
  In fit>iFit at 320
  In fit at 109 

f = 

     General model:
     f(x) = a*x.^2+b*x+c
     Coefficients (with 95% confidence bounds):
       a =     -0.2571  (-0.5681, 0.05386)
       b =       2.049  (0.791, 3.306)
       c =       -0.86  (-2.016, 0.2964)



法2:

x=[1;1.5;2;2.5;3];y=[0.9;1.7;2.2;2.6;3];
%use c=0;
c=0;
p1=fittype(@(a,b,x) a*x.^2+b*x+c)
f1=fit(x,y,p1)
%use c=1;
c=1;
p2=fittype(@(a,b,x) a*x.^2+b*x+c)
f2=fit(x,y,p2)
%predict c
p3=fittype(@(a,b,c,x) a*x.^2+b*x+c)
f3=fit(x,y,p3)

%show results
scatter(x,y);%scatter point
c1=plot(f1,'b:*');%blue
hold on
plot(f2,'g:+');%green
hold on
plot(f3,'m:*');%purple
hold off


2018-12-21 15:44:23 yql_617540298 阅读数 1044

一、最小二乘法拟合曲线

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

#自定义函数 e指数形式
def func(x, a, b,c):
    return a*np.sqrt(x)*(b*np.square(x)+c)

#定义x、y散点坐标
x = [10,20,30,40,50,60,70,80]
x = np.array(x)
y = [158,455,265,152,263,813,562,126]
y = np.array(y)

#非线性最小二乘法拟合
popt, pcov = curve_fit(func, x, y)
#获取popt里面是拟合系数
print(popt)
a = popt[0]
b = popt[1]
c = popt[2]
yvals = func(x,a,b,c) #拟合y值
print('popt:', popt)
print('系数a:', a)
print('系数b:', b)
print('系数c:', c)
print('系数pcov:', pcov)
print('系数yvals:', yvals)
#绘图
plot1 = plt.plot(x, y, 's',label='original values')
plot2 = plt.plot(x, yvals, 'r',label='polyfit values')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc=4) #指定legend的位置右下角
plt.title('curve_fit')
plt.show()

二、高斯分布拟合曲线

import numpy as np
import math
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit


#自定义函数 e指数形式
def func(x, a,u, sig):
    return  a*(np.exp(-(x - u) ** 2 /(2* sig **2))/(math.sqrt(2*math.pi)*sig))*(431+(4750/x))


#定义x、y散点坐标
x = [10,20,30,40,50,60,70,80]
x=np.array(x)
# x = np.array(range(20))
print('x is :\n',x)
y = [158,455,265,152,263,813,562,126]
y = np.array(y)
print('y is :\n',y)

popt, pcov = curve_fit(func, x, y,p0=[3.1,4.2,3.3])
#获取popt里面是拟合系数
a = popt[0]
u = popt[1]
sig = popt[2]


yvals = func(x,a,u,sig) #拟合y值
print(u'系数a:', a)
print(u'系数u:', u)
print(u'系数sig:', sig)

#绘图
plot1 = plt.plot(x, y, 's',label='original values')
plot2 = plt.plot(x, yvals, 'r',label='polyfit values')
plt.xlabel('x')
plt.ylabel('y')
plt.legend(loc=4) #指定legend的位置右下角
plt.title('curve_fit')
plt.show()

三、多项式拟合曲线

import numpy as np
import matplotlib.pyplot as plt

#定义x、y散点坐标
#x = [10,20,30,40,50,60,70,80]
#y = [158,455,265,152,263,813,562,126]
#x = [16,32,48,64,80,96,112,128,144,160,176,192,208,224,240,256,272,288,304]
x = [0,16,32,48,64,80,96,112,128,144,160,176,192,208,224,240,256,272,288,304,320,336,352,368,384,400,416,432,448,464,480,496,]
x = np.array(x)
#y = [506,506,506,506,506,506,506,506,506,505,505,505,505,505,505,505,506,505,504]
y = [340,338,345,348,348,349,50,350,350,350,350,350,350,350,350,350,350,349,348,348,348,347,347,348,348,347,347,347,347,348,347,346]
y = np.array(y)
#用3次多项式拟合
f1 = np.polyfit(x, y, 3)
p1 = np.poly1d(f1)
yvals = p1(x)#拟合y值

#x1 = [32,48,64,80,96,112,128,144,160,176,192,208,224,240,256,272,288,304,320]
x1 = [16,32,48,64,80,96,112,128,144,160,176,192,208,224,240,256,272,288,304,320,336,352,368,384,400,416,432,448,464,480,496,512]
x1 = np.array(x1)
#y1 = [529,528,528,529,529,529,529,529,529,529,528,528,528,528,528,528,528,528,529]
y1 = [370,367,376,378,378,379,379,380,380,380,379,379,379,379,378,378,378,378,377,376,376,375,375,372,372,372,372,375,375,372,372,373]
y1 = np.array(y1)
f2 = np.polyfit(x1,y1,3)
p2 = np.poly1d(f2)
yvals_2 = p2(x1)
#也可使用yvals=np.polyval(f1, x)
#绘图
plot1 = plt.plot(x, y, 's',label='original values')
plot2 = plt.plot(x, yvals, 'r',label='polyfit values')
plt.xlabel('x')
plt.ylabel('y')

plot3 = plt.plot(x1, y1, 's', label = 'original values')
plot4 = plt.plot(x1, yvals_2, 'r',label='',color='green')

#plt.axis('off')
#plt.legend(loc=4) #指定legend的位置右下角
#plt.title('polyfitting')
#plt.show()
plt.savefig("F:/a.jpg")

2019-01-23 09:25:36 qq_41149269 阅读数 7870

线性拟合

已知如下图像的x,y坐标,x = [1.0, 1.5, 2.0, 2.5, 3.0],y = [0.9, 1.7, 2.2, 2.6, 3.0],如何用一条直线去拟合下列散点?

代码:

x = [1.0, 1.5, 2.0, 2.5, 3.0]';
y = [0.9, 1.7, 2.2, 2.6, 3.0]';
a = polyfit(x,y,1)  % a会返回两个值,[斜率,x=0时y的值]
xi = 1:0.1:3;
yi = polyval(a,xi);
plot(x,y,'o',xi,yi);

拟合后的图像如下:

非线性拟合

普通非线性拟合:已知如下图像的x,y坐标,x = [1.0, 1.5, 2.0, 2.5, 3.0],y = [0.9, 1.7, 2.2, 2.6, 3.0],如何用一条曲线a*x+b*sin(x)+c去拟合下列散点?

代码:

x = [1.0, 1.5, 2.0, 2.5, 3.0]';
y = [0.9, 1.7, 2.2, 2.6, 3.0]';
p = fittype('a*x+b*sin(x)+c');
f = fit(x,y,p)   % f会返回a,b,c的值
plot(f,x,y);

指数非线性拟合:如何拟合1790-1900年美国人口指数增长模型

思路:

实现代码:

t = 1790:10:1900;
p = [3.9 5.3 7.2 9.6 ...
    12.9 17.1 23.2 31.4 ...
    38.6 50.2 62.9 76.0];
Y = log(p); % Y = log(p) 返回数组p中每个元素的自然对数ln(x)
X = t;
a = polyfit(X,Y,1)
x0 = exp(a(2)); r = a(1);
ti = 1790:1900;
pti= x0*exp(r*ti);
plot(t,p,'o',ti,pti,'m')
xlabel('Year')
ylabel('Population')

对数形式的非线性拟合:

%% 对数形式非线性回归
x = [1.5, 4.5, 7.5,10.5,13.5,16.5,19.5,22.5,25.5];
y = [7.0,4.8,3.6,3.1,2.7,2.5,2.4,2.3,2.2];
plot(x, y, '*', 'linewidth', 1) % 这里的linewidth指的是散点大小
m1 = @(b,x) b(1) + b(2)*log(x);
nonlinfit1 = fitnlm(x,y,m1,[0.01;0.01])
b = nonlinfit1.Coefficients.Estimate;
Y1 = b(1,1) + b(2,1)*log(x);
hold on 
plot(x, Y1, '--k', 'linewidth',2)

2018-03-19 15:47:39 Sirius_007 阅读数 8048

1.最小二乘拟合

    最简单,但是受离群点的影响比较大,鲁棒性不强。

2.梯度下降法

3.高斯牛顿、列-马算法

opencv 直线拟合

阅读数 6078