matlab图像处理,ROI区域分割,以及直线提取

针对一张图片,想提取图像中的道路标线。因为上半部分不需要,所以想用roi区域分割法,提取图像的下半部分,在此基础上,用直线提取,提取道路标线,并用起止点形式将直线图片说明表示出来。

直线提取我做过,,你可以试试用霍夫变换提取直线,,当然霍夫变换前提需要进行边缘,
边缘提取首推canny算子,相对其他几个算子,这个算子对噪声更适应,效果更好

针对你这幅图,,唉,直线还是比较多的提取时候得在考虑考虑加点策略。

最后就是你说那个感兴趣区域,,针对这张图地面有什么特征,,唉,反光还比较严重,感兴趣区域不太好提。,,不过可以在提取直线的策略上试一下,
比如,站在路中间拍的时候,道路两边直线的斜率回落在某个特定区间,可以加个区间把别的直线排除,。

图片说明嘿嘿,我也是渣渣,说的不好多多指教。

ROI 提取,你就自己选取下部分的区域, 至于直线提取的话,可以试试 LSD 算法, matlab代码到没有, 有的只是 matlab 调用 LSD的 dll的 混合编程代码
lsd.mexw64

图片说明

ROI的提取,自己按照条件进行截取

别废话,直接上代码

% 功能:matlab图像处理实现直线识别(拟合角平分线)
% 说明:此程序可直接运行
% 运行前请确保子程序文件zikuai.m存在

%第1步
close all
I=imread('1.jpg'); % 读取图像
figure
imshow(I) % 显示原始图像
I=rgb2gray(I); % 彩色图像转换成灰度图

% I=im2bw(I); % 二值化
I=edge(double(I)); % 检测图像的边缘
figure
imshow(I) % 显示边缘检测的结果

%第2步
[m,n]=size(I); %计算图像的尺寸

M=3; %定义X方向分割的块数
N=3; %定义Y方向分割的块数
mm=floor(m/M); %子块行的长度
nn=floor(n/N); %子块列的长度
count=1; %计数器
figure
for i=1:M
for j=1:N
A=I((i-1)*mm+1:i*mm,(j-1)*nn+1:j*nn); %分割原图像,得到一个子块
subplot(M,N,count)
imshow(A) %显示一个子块
zuoshangjiao=[(i-1)*mm+1 (j-1)*nn+1]; %子块左上角的坐标
[x,y,k,b]=zikuai(A,zuoshangjiao); %得到子块里白色像素点拟合得到的直线的斜率k和截距b(调用zikuai函数)
X{count}=x; %保存子块里所有白色像素的x坐标
Y{count}=y; %保存子块里所有白色像素的y坐标
K(count)=k; %保存子块里拟合得到的直线的斜率k
B(count)=b; %保存子块里拟合得到的直线的截距b
count=count+1; %计数器加1,进行下一个子块的计算
end
end

%第3步
KK=K(~isnan(K)); %去掉K中的NaN(白色像素点少于10的子块)
BB=B(~isnan(B)); %去掉B中的NaN(白色像素点少于10的子块)

mean_K=mean(KK); %求所有斜率的平均值
mean_B=mean(BB); %求所有截距的平均值

figure
subplot(2,1,1)
plot(KK,'-o')
title('各子块拟合得到的直线k值')
subplot(2,1,2)
plot(BB,'-o')
title('各子块拟合得到的直线b值')

count1=1;
count2=1;
for i=1:length(K)
IF ~isnan(K(i))
if K(i)>mean_K %大于斜率平均值的子块,将这些子块的白色像素点位置集合到cell型数组X1和Y1(分别存x和y)
X1{count1}=X{i};
Y1{count1}=Y{i};
count1=count1+1;
else %小于斜率平均值的子块,将这些子块的白色像素点位置集合到cell型数组X2和Y2(分别存x和y)
X2{count2}=X{i};
Y2{count2}=Y{i};
count2=count2+1;
end
end
end

XX1=[];
YY1=[];
XX2=[];
YY2=[];

for i=1:length(X1) %大于斜率平均值的子块,将这些子块的白色像素点位置集合到double型数组里,方便计算
XX1=[XX1;X1{i}];
YY1=[YY1;Y1{i}];
end

for i=1:length(X2) %小于斜率平均值的子块,将这些子块的白色像素点位置集合到double型数组里,方便计算
XX2=[XX2;X2{i}];
YY2=[YY2;Y2{i}];
end

%%%%%直线1和直线2被从图像里提取出来了分别为XX1,YY1和XX2,YY2
%离散点拟合得到直线1的斜率k1和截距b1
A1=[XX1,ones(length(XX1),1)];
kb1=A1\YY1;
k1=kb1(1);
b1=kb1(2);

%离散点拟合得到直线2的斜率k2和截距b2
A2=[XX2,ones(length(XX2),1)];
kb2=A2\YY2;
k2=kb2(1);
b2=kb2(2);

xx0=[1 m];
yy0=[1 n];

yy1=k1*xx0+b1; %得到直线1上的两点,以便绘制直线1
yy2=k2*xx0+b2; %得到直线3上的两点,以便绘制直线2

%%%%绘制拟合得到的直线和分离出来的离散点
%直线1
figure
axis([1,m,1,n]) %设定显示范围
hold on
scatter(XX1,YY1,'LineWidth',5) %绘制直线1对应的白色像素位置
plot(xx0,yy1,'r','LineWidth',3) %绘制拟合到的直线1

%直线2
hold on
scatter(XX2,YY2,'k','LineWidth',5) %绘制直线2对应的白色像素位置
plot(xx0,yy2,'y','LineWidth',3) %绘制拟合到的直线2


%第4步

%求两条直线的交点
X0=(b2-b1)/(k1-k2);
Y0=k1*X0+b1;

alpha=atan(k1); %直线1与x夹角
beta=atan(k2); %直线2与x夹角

K01=tan((alpha+beta)/2); %角平分线1的斜率
K02=tan(-pi/2+(alpha+beta)/2); %角平分线2的斜率

B01=Y0-K01*X0; %角平分线1的截距
B02=Y0-K02*X0; %角平分线2的截距

%绘制角平分线
xx0=[1 m];
yy0=[1 n];

YY1=K01*xx0+B01; %角平分线1
YY2=K02*xx0+B02; %角平分线2
plot(xx0,YY1); %绘制角平分线1
plot(xx0,YY2); %绘制角平分线2

view([90 90])

查看原文