如何在matlab中检测平滑曲线
How to detect smooth curves in matlab
我正在尝试检测图像中弯曲的传送带。我使用以下代码使用霍夫变换来检测其边缘
%# load image, and process it
I = imread('ggp.jpg');
g = rgb2gray(I);
bw = edge(g,'Canny');
[H,T,R] = hough(bw);
P = houghpeaks(H,500,'threshold',ceil(0.4*max(H(:))));
% I apply houghlines on the grayscale picture, otherwise it doesn't detect
% the straight lines shown in the picture
lines = houghlines(g,T,R,P,'FillGap',5,'MinLength',50);
figure, imshow(g), hold on
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
deltaY = xy(2,2) - xy(1,2);
deltaX = xy(2,1) - xy(1,1);
angle = atan2(deltaY, deltaX) * 180 / pi;
if (angle == 0)
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');
% Plot beginnings and ends of lines
plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');
plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');
end
end
如图所示,两条直线成功检测到传送带的顶部和底部边缘,但我不知道如何检测它是否弯曲(图中是弯曲的)以及如何计算那个程度。
下图(红色)大致为手工绘制的曲线:
我在 matlab 中没有找到 Hough 变换的代码或函数来检测这种平滑曲线(例如,二次多项式:y= a*x^2
)。也欢迎任何其他解决方案。
这是原图:
看看你检测传送带的直线,我假设你可以将你的处理集中在感兴趣的区域周围(图像中的第 750 到 950 行)。
从那一点开始:
oimg = imread('http://i.stack.imgur.com/xfXUS.jpg'); %// read the image
gimg = im2double( rgb2gray( oimg( 751:950, :, : ) ) ); %// convert to gray, only the relevant part
fimg = imfilter(gimg, [ones(7,50);zeros(1,50);-ones(7,50)] ); %// find horizontal edge
Select只有区域中心周围的强水平边缘像素
[row, col] = find(abs(fimg)>50);
sel = row>50 & row < 150 & col > 750 & col < 3250;
row=row(sel);
col=col(sel);
对这些边缘点拟合一个二阶多项式和一条直线
[P, S, mu] = polyfit(col,row,2);
[L, lS, lmu] = polyfit(col, row, 1);
绘制估计曲线
xx=1:4000;
figure;imshow(oimg,'border','tight');
hold on;
plot(xx,polyval(P,xx,[],mu)+750,'LineWidth',1.5,'Color','r');
plot(xx,polyval(L,xx,[],lmu)+750,':g', 'LineWidth', 1.5);
结果是
您可以直观地体会到二阶拟合P
如何更好地拟合传送带的边界。看第一个系数
>> P(1)
ans =
1.4574
你看曲线的x^2
系数不可忽略,明显不是直线
我正在尝试检测图像中弯曲的传送带。我使用以下代码使用霍夫变换来检测其边缘
%# load image, and process it
I = imread('ggp.jpg');
g = rgb2gray(I);
bw = edge(g,'Canny');
[H,T,R] = hough(bw);
P = houghpeaks(H,500,'threshold',ceil(0.4*max(H(:))));
% I apply houghlines on the grayscale picture, otherwise it doesn't detect
% the straight lines shown in the picture
lines = houghlines(g,T,R,P,'FillGap',5,'MinLength',50);
figure, imshow(g), hold on
for k = 1:length(lines)
xy = [lines(k).point1; lines(k).point2];
deltaY = xy(2,2) - xy(1,2);
deltaX = xy(2,1) - xy(1,1);
angle = atan2(deltaY, deltaX) * 180 / pi;
if (angle == 0)
plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');
% Plot beginnings and ends of lines
plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');
plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');
end
end
如图所示,两条直线成功检测到传送带的顶部和底部边缘,但我不知道如何检测它是否弯曲(图中是弯曲的)以及如何计算那个程度。
下图(红色)大致为手工绘制的曲线:
我在 matlab 中没有找到 Hough 变换的代码或函数来检测这种平滑曲线(例如,二次多项式:y= a*x^2
)。也欢迎任何其他解决方案。
这是原图:
看看你检测传送带的直线,我假设你可以将你的处理集中在感兴趣的区域周围(图像中的第 750 到 950 行)。
从那一点开始:
oimg = imread('http://i.stack.imgur.com/xfXUS.jpg'); %// read the image
gimg = im2double( rgb2gray( oimg( 751:950, :, : ) ) ); %// convert to gray, only the relevant part
fimg = imfilter(gimg, [ones(7,50);zeros(1,50);-ones(7,50)] ); %// find horizontal edge
Select只有区域中心周围的强水平边缘像素
[row, col] = find(abs(fimg)>50);
sel = row>50 & row < 150 & col > 750 & col < 3250;
row=row(sel);
col=col(sel);
对这些边缘点拟合一个二阶多项式和一条直线
[P, S, mu] = polyfit(col,row,2);
[L, lS, lmu] = polyfit(col, row, 1);
绘制估计曲线
xx=1:4000;
figure;imshow(oimg,'border','tight');
hold on;
plot(xx,polyval(P,xx,[],mu)+750,'LineWidth',1.5,'Color','r');
plot(xx,polyval(L,xx,[],lmu)+750,':g', 'LineWidth', 1.5);
结果是
您可以直观地体会到二阶拟合P
如何更好地拟合传送带的边界。看第一个系数
>> P(1)
ans =
1.4574
你看曲线的x^2
系数不可忽略,明显不是直线