2014-09-20 376 views
1

我想用Matlab解释我的问题。我的目标是在从照片坦克获得自由液面而要做到这一点,我已经使用这个算法:Matlab - 从边缘创建x,y曲线

A = 'C:\foto\img3.bmp'; 
B = imread(A, 'bmp'); 
figure(1), imshow(B); 
C = rgb2gray(B); 
level = graythresh(C); 
bw = im2bw(C,level); 
bw = bwareaopen(bw, 50); 
figure, imshow(bw); 
BW1 = edge(bw,'canny'); 
figure(2), imshow(BW1); 
imwrite(BW1, 'C:\foto\im1_edge.bmp', 'bmp') 

现在我有表面边缘为白色,与黑色的背景。 接下来我也只能检测白色像素的位置:

I= imread('C:\foto\img3_edge.bmp'); 
imshow(I); 
[r c] =size(I); 
for j=1:c 
    for i=1:r 
    if(I(i,j)==1)     
    [i j] 
    end 
    end 
end 

在这一点上,我怎么可以报告(含宏,自动可能)每对夫妇坐标的笛卡尔(x,y)平面?我的目标是从边缘获得重建的类型“y = f(x)”的函数。 我和另一个边缘尝试,并用油漆修改,删除所有无用像素的图像,例子是这样的一个:

http://i59.tinypic.com/20jh1g2.jpg

与代码:

I = im2bw(I); 

它返回我的错误“警告:输入图像已经是二进制。”接下来使用的代码:

[r c] = find(I), output = [r c]; 
plot(r,c,'.') 

我得到这一个:

http://i59.tinypic.com/2iqmqvl.jpg

此外,当我尝试在cftool插入R作为XDATA和c如YDATA,我得到了同样的问题,并且当我使用“Interpolant”装配,它会返回一个错误.....为什么?

请帮助我,谢谢大家! :-) PS:对不起,太长的帖子:)

+0

使用'polynomial'这种类型的曲线 – Hoki 2014-09-20 10:16:56

+0

您可以简化您的白点检测装修:取而代之的是两个for循环使用:* [行col] = find(I == 1)* – zinjaai 2014-09-20 12:23:02

回答

2

我不知道你想适用于你的数据是什么类型的适合。以下代码将适合数据上的三阶多项式。

I = imread('20jh1g2.jpg'); 
I = im2bw(I); 
imshow(I); 

[r, c] = find(I); 
figure; 
plot(c,r,'.'); 
hold on; 
f = fit(c, r, 'poly3'); 
plot((min(c):max(c)),f(min(c):max(c)), 'red', 'LineWidth', 3); 

将产生:

3rd order polynomial fit

旋转可以由轴是如何定义进行说明。在您的图像中,Y轴从顶部的0开始到底部的374。您可以使用以下代码将您的拟合结果转换回二进制映像;

x = (min(c):max(c))'; 
y = round(f(x)); 
I = zeros(size(I)); 
I(y +((x-1)*size(I,1))) = 1; 
figure 
imshow(I); 

将产生:

binary image of fit

拟合的结果,f存储在cfit对象。您可以通过为其提供x的值来评估此功能,如上所示。函数系数可以通过在命令窗口中打印cfit对象的字段来找到;

f = 

    Linear model Poly3: 
    f(x) = p1*x^3 + p2*x^2 + p3*x + p4 
    Coefficients (with 95% confidence bounds): 
     p1 = -6.252e-06 (-6.542e-06, -5.963e-06) 
     p2 = 0.001753 (0.001588, 0.001918) 
     p3 =  -0.3667 (-0.3932, -0.3401) 
     p4 =  290.4 (289.3, 291.6) 

要翻转参考框架内的函数并计算质心,您可以使用它;

I = imread('20jh1g2.jpg'); 
I = im2bw(I); 

[r, c] = find(I); 
r = -r + size(I,1); 
f = polyfit(c, r, 3); 
plot((min(c):max(c)),polyval(f,(min(c):max(c))), 'red', 'LineWidth', 3); 
hold on; 

xf = [f 0]; 
fx2 = sym2poly(poly2sym(f)^2); 
centroid = 1/polyval(polyint(f),size(I,2)) * [polyval(polyint(xf),size(I,2)) 1/2 * polyval(polyint(fx2),size(I,2))]; 
plot(centroid(1),centroid(2),'X'); 

将产生:

3rd order polynomial fit with centroid

+0

感谢@ 0xMB的帮助,这个结果是一个很好的观点!但是我怎样才能明确地设置旋转的曲线?因为如果我使用** plot(f)**曲线结果旋转了。而且,我可以检测曲线下方区域的质量质心吗? – Firefly 2014-09-21 09:48:27

+0

萤火虫,你能否详细解释一下你想要达到的目标?你为什么要画阴影?不管你如何绘制拟合,因为x和y之间的关系是相同的。一旦获得多项式的系数,找到曲线下面积的质心就是简单的数学运算。 – 0xMB 2014-09-22 07:21:44

+0

0xMB抱歉我的英文不好,可能我没有解释清楚。我的目标是通过实验测试(照片)比较2个无水表面:1和模拟Fluent(或Flow3D)的其他1个水表面。我只想获得2条曲线(没有图像的其余部分),所以我可以比较它们,以米(罐的长度)为单位设置坐标(x,y),并验证通过Fluent模拟得出的误差百分比。接下来,我还想获得瞬态模拟中每个时间步的质量质心,所以我可以绘制一条通过所有这些点的曲线 – Firefly 2014-09-22 08:14:18