在Matlab中寻找和绘制抛物线

4

我一直在尝试在图片中找到抛物线。为了起步,我拍了一张有黑色抛物线的白色背景图片。然后使用“find”命令在图像上找到了黑色像素。

[yi xi] = find(im<10); % im is the image with black parabola and white background

之后,我从集合中随机选取了3个点,并使用符号工具箱解决了抛物线方程,具体方法如下:

syms x y;
%solve them for the parabola equation
A  = [ x^2 x y 1 ;x0^2 x0 y0 1; x1^2 x1 y1 1; x2^2 x2 y2 1];

这里是坐标系中的位置:

%(x0,y0) = (104,137)

%(x1,y1) = (244,161)

%(x2,y2) = (300,229)

S = solve(det(A),y);

然后我得到了系数a、b、c,分别为

a = 0.0100

b = -1.6800

c = 254.1900

其中a、b和c分别代表:

a*x^2 + b*x + c = y;

现在我已经得到了方程,通过放入系数值并取出来绘制抛物线。

 xx = 1:300;

 yy = a*xx.^2 + b*xx +c ;

然后我在图像上绘制抛物线,如下:

 plot(xx,yy,'-');

为了确认我选择的点是正确的,我在图像上绘制了选定的点,它们恰好位于图像中的抛物线上。所以这不是问题。
问题如下:
1. 我绘制的抛物线(蓝色)不在图像中的抛物线(黑色)上。 2. 当我将x坐标的值放入上述方程时,y的值与y坐标的值不同。
例如:(104,137) 0.0100*104*104 -1.68*104 + 254.19 = 108.16 - 174.72 + 254.19 = 187.63,而应该是137。
我的抛物线是错误的。任何帮助都将不胜感激。图片如下: parabola from the equation(blue) plotted on the image(black)

我想知道为什么蓝色的抛物线不在黑色的抛物线上。星号表示我用来生成系数(a、b、c)的点。黑色的抛物线是原始图像。蓝色的抛物线是我用上述第一个方程绘制的。y值是通过放入(a、b、c)计算的,而x值则从图像的列数1到300取值。因此,x = 1:300,y = ax^2+bx+c。绘图使用plot(xx,yy,'-')。 - t0mkaka
1
我认为在计算系数时出现了一些问题。请更新问题并包含相关代码。(最好提供三个点的坐标以及相应的代码) - DasKrümelmonster
您还可以展示您提取的系数值和原始方程(带有其自己的系数)的值。 - Buck Thorn
1
你可以更简单地找到抛物线:使用polyfit函数。 - Andrey Rubshtein
正如@Andrey建议的那样,[p, S, mu] = polyfit(x,y,n)是拟合抛物线的一种稳健方式。 - Buck Thorn
显示剩余4条评论
2个回答

2
我认为你在计算a、b和c的时候可能会四舍五入。我使用拟合函数(拟合类型为poly2)尝试了你提到的三个点,我的a、b、c分别是0.0053、-1.6802和254.1895(或者使用format long时可以添加更多小数位)。同样地,当使用你提供的代码时,solve的输出如下:
S = (73*x^2)/13720 - (5763*x)/3430 + 87187/343
S2 = double(coeffs(S))

S2 =

  254.1895   -1.6802    0.0053

这使我得到了与fit/poly2相同的a、b和c(仅从外观上看,73/13720的输出不能为0.01)。而且,如果我使用你提供的相同代码在原始点上绘制这条曲线,它也可以正常工作。因此,我能看到的唯一剩下的错误来源是您用于从solve的输出中提取a、b和c值的任何代码中的某种舍入误差。

1
你说得对。我正在使用roundn(a,-2)将数字四舍五入到两位小数。我这样做是因为我正在实现用于抛物线的随机Hough变换,而在比较不同抛物线系数的双精度值时出现了问题。非常抱歉我错过了四舍五入部分,因为我认为它微不足道。非常感谢。 - t0mkaka
@t0mkaka 你可以在解决方程之前对其进行归一化处理(去除数据的平均值并将其除以标准差),这应该会使解决方案更加鲁棒,不易被截断。 - Buck Thorn
1
@TryHArd 规范化方程是很好的。感谢你的提示。 - t0mkaka

0
以下代码是可行的。imshow方法将纵坐标和横坐标的直观含义与plot中的使用方式进行了交换,这可能会导致重叠问题。您的问题可能源于绘制不同函数时(imshow或相关图像显示例程与plot)如何定义您的坐标系,特别是图像中原点的位置。以下是我的代码:
% create image of parabola
k =[-0.3 10 10];
x = [1:0.1:50];
y = round(k(1)*x.^2 + k(2)*x + k(3));
crd = unique(round([x(:) y(:)]),'rows');
Nx = 100;
Ny = 100;
img = ones(Nx,Ny)*255;
iok = find((crd(:,1)>0) & (crd(:,1)<=Nx) & (crd(:,2)>0) & (crd(:,2)<=Ny));
indx = sub2ind([Nx Ny],crd(iok,1),crd(iok,2));
img(indx) = 0;
imshow(img)

接下来,我们拟合抛物线

% pick three points:
x0 = crd(1,1);
y0 = crd(1,2);
x1 = crd(80,1);
y1 = crd(80,2);
x2 = crd(160,1);
y2 = crd(160,2);
% plot these on the original image
hold on
plot(y0,x0,y1,x1,y2,x2,'Markersize',20,'Linestyle','none','Marker','x','Color','r')

按照您所示的精确解决了方程,结果如下:

S = -1094/3627*x^2+12073/1209*x+37415/3627

叠加拟合方程

a= -1094/3627;
b = 12073/1209;
c = 37415/3627;
xx = 1:100;
yy = a*xx.^2 + b*xx +c ;
% then I plot the parabola on the image as
plot(yy,xx,'g--');

一个不太好看的图(绿色=拟合,红色叉号=选定点,蓝色=二次曲线绘制而没有交换 x 和 y 的顺序):

enter image description here


1
谢谢你的努力。但是@nkjt的答案解决了我当前的问题。我也考虑过在Matlab中改变图片的坐标系,并进行了必要的更改。再次感谢。 - t0mkaka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接