Matlab边缘检测问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Matlab边缘检测问题相关的知识,希望对你有一定的参考价值。

本人正在做用Sobel算子的边缘检测,遇到一个问题,首先说明我的目的是将像素的坐标做为x,y轴,像素的梯度做为z轴,我在网上找到一个代码修改后如下:
clear
clc
X=imread('F:\学习\Abschlussarbeit\素材\Lena原图.jpg'); %读入要处理的图像
S=size(X); %图像的大小(长和宽)
g=zeros(S); %定义一个大小为S的空矩阵
figure(1)
image(X)
X=double(X); %把图变为十进制数
colormap(gray(256))
title('灰度图');
for i=2:S(1)-1
for j=2:S(2)-1
Dx=(X(i+1,j-1)-X(i-1,j-1)+2*(X(i+1,j)-X(i-1,j))+X(i+1,j+1)-X(i-1,j+1))^2; %Sobel算子的Dx(垂直梯度)
Dy=(X(i-1,j+1)-X(i-1,j-1)+2*(X(i,j+1)-X(i,j-1))+X(i+1,j+1)-X(i+1,j-1))^2; %Sobel算子的Dy(水平梯度)
g(i,j)=round(sqrt(Dx+Dy)); %此为梯度模round为取整函数
end
end

我的问题是:
g(i,j)的结果是一个矩阵(存贮所有像素梯度的矩阵)
如果我想将i,j,g(i,j)分别作为x y z坐标画散点图(plot命令等)那么我该如何操作?
直接写肯定不行,因为g是个二维向量,如何做才能将g变成关于i,j的二元函数?我听说可以压缩矩阵再还原,可是我想最好要比较方便的方法!
谢谢各位高手!
补充一个问题:我操作完这步之后 有没有简单的命令可以实现这个效果:在描绘出的三维散点图上任意一点画圆(半径可选),如果圆球内存在点该中心点被标记。 我想到的就是直接用两点间距离的数学公式实现,有没有别的matlab特定函数?谢谢!
回一楼!我的算法不完全是Sobel算法

用mesh语句似乎可以,具体也不了解你的情况,感觉怪怪的,发一段我以前些的程序,用罗伯特算子写的,把算子一改就是sobel了。两种边缘检测近似算法奉上:
clc
close all
clear all
%%%生成高斯平滑滤波模板%%%
%%%%%%%%%%%%%%%%%%%%%%%%%
hg=zeros(3,3); %设定高斯平滑滤波模板的大小为3*3
delta=0.5;
for x=1:1:3
for y=1:1:3
u=x-2;
v=y-2;
hg(x,y)=exp(-(u^2+v^2)/(2*pi*delta^2));
end
end
h=hg/sum(hg(:));
%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%读入图像%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%

f = imread('1111.tif'); % 读入图像文件
f=rgb2gray(im2double(f));
imshow(f)
title('原始图像');
[m,n]=size(f);
ftemp=zeros(m,n);
rowhigh=m-1;
colhigh=n-1;
%%%高斯滤波%%%
for x=2:1:rowhigh-1
for y=2:1:colhigh-1
mod=[f(x-1,y-1) f(x-1,y) f(x-1,y+1); f(x,y-1) f(x,y) f(x,y+1);f(x+1,y-1) f(x+1,y) f(x+1,y+1)];
A=h.*mod;
ftemp(x,y)=sum(A(:));
end
end
f=ftemp
figure,imshow(f)
title('通过高斯滤波器后的图像');

% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %%%利用roberts算子进行边缘检测%%%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sx=[-1 -2 -1;0 0 0;1 2 1];
sy=[-1 0 1;-2 0 2;-1 0 1];
for x=2:1:rowhigh-1
for y=2:1:colhigh-1
mod=[f(x-1,y-1) f(x-1,y) f(x-1,y+1); f(x,y-1) f(x,y) f(x,y+1);f(x+1,y-1) f(x+1,y) f(x+1,y+1)];
fsx=sx.*mod;
fsy=sy.*mod;
ftemp(x,y)=sqrt((sum(fsx(:)))^2+(sum(fsy(:)))^2);
end
end
fr=im2uint8(ftemp);
figure,imshow(fr)
title('用roberts算子边缘检测的原始图像');

%%%域值分割%%%
TH1=60; %设定阈值
for x=2:1:rowhigh-1
for y=2:1:colhigh-1
if (fr(x,y)>=TH1)&((fr(x,y-1) <= fr(x,y)) & (fr(x,y) > fr(x,y+1)) )
fr(x,y)=200;
elseif(fr(x,y)>=TH1)&( (fr(x-1,y) <=fr(x,y)) & (fr(x,y) >fr(x+1,y)))
fr(x,y)=200;
else fr(x,y)=50;
end
end
end
figure,imshow(fr)
title('用roberts算子边缘检测并细化后的图像');
%%%%%%%%%%%%%%%%%%%%%%%%%%
利用第一种近似算法进行边缘检测%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%3*3的sobel算子%%%%%%%%
sx=[-1 -2 -1;0 0 0;1 2 1];
sy=[-1 0 1;-2 0 2;-1 0 1];
%sx=[0 1 2;-1 0 1;-2 -1 0];
%sy=[-2 -1 0;-1 0 1;0 1 2];
for x=2:1:rowhigh-1
for y=2:1:colhigh-1
mod=[f(x-1,y-1) f(x-1,y) f(x-1,y+1); f(x,y-1) f(x,y) f(x,y+1);f(x+1,y-1) f(x+1,y) f(x+1,y+1)];
fsx=sx.*mod;
fsy=sy.*mod;
ftemp(x,y)=abs(sum(fsx(:)))+abs(sum(fsy(:)));
end
end
fs=im2uint8(ftemp);
figure,imshow(fs)
title('用第一种近似算法进行边缘检测的原始图像');
%%%域值分割%%%
TH2=200; %设定阈值
for x=2:1:rowhigh-1
for y=2:1:colhigh-1
if (fs(x,y)>=TH2)&((fs(x,y-1) <= fs(x,y)) & (fs(x,y) > fs(x,y+1)) )
fs(x,y)=200;
elseif(fs(x,y)>=TH2)&( (fs(x-1,y) <=fs(x,y)) & (fs(x,y) >fs(x+1,y)))
fs(x,y)=200;
else fs(x,y)=50;
end
end
end
figure,imshow(fs)
title('采用第一种近似算法进行边缘检测后的图像');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%利用第二种近似算法进行边缘检测%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%3*3的sobel算子%%%%%%%%
sx=[-1 -2 -1;0 0 0;1 2 1];
sy=[-1 0 1;-2 0 2;-1 0 1];
%sx=[0 1 2;-1 0 1;-2 -1 0];
%sy=[-2 -1 0;-1 0 1;0 1 2];
for x=2:1:rowhigh-1
for y=2:1:colhigh-1
mod=[f(x-1,y-1) f(x-1,y) f(x-1,y+1); f(x,y-1) f(x,y) f(x,y+1);f(x+1,y-1) f(x+1,y) f(x+1,y+1)];
fsx=sx.*mod;
fsy=sy.*mod;
ftemp(x,y)=max(abs(sum(fsx(:))),abs(sum(fsy(:))));
end
end
fs=im2uint8(ftemp);
figure,imshow(fs)
title('用第二种近似算法进行边缘检测的原始图像');
%%%域值分割%%%
TH2=200; %设定阈值
for x=2:1:rowhigh-1
for y=2:1:colhigh-1
if (fs(x,y)>=TH2)&((fs(x,y-1) <= fs(x,y)) & (fs(x,y) > fs(x,y+1)) )
fs(x,y)=200;
elseif(fs(x,y)>=TH2)&( (fs(x-1,y) <=fs(x,y)) & (fs(x,y) >fs(x+1,y)))
fs(x,y)=200;
else fs(x,y)=50;
end
end
end
figure,imshow(fs)
title('采用第二种近似算法进行边缘检测后的图像');
参考技术A 第一个问题
既然g是二维,每个像素都计算了,你要求的z坐标是什么样子的?要求是什么。
你可以用mean(g)得到每列的平均值,sum(g)得到每列的和
这样就维数就一样了。
mean(g,1) mean(g,2)这类可以求行的和或者列的和。看你的要求了。
还有画三维用scatter3 是吧?
参考资料看我给的链接,这个就是你要的吧?看看scatter3的介绍。
scatter3(X(:),Y(:),Z(:),S(:),C(:),'filled'), view(-60,60)
这句貌似就是选择被填充的球形部分。

参考资料:http://www.mathworks.com/access/helpdesk/help/techdoc/ref/scatter3.html

参考技术B 这个网站上有程序,你找一下
原来看到过

用sobel算子
不过最好先转换成bmp格式
我不记得matlab是不是识别tif
程序很简单
不过要做好的效果还是比较复杂

一般是载入图像
然后用算子计算,同时设定阈值
如果高于阈值就是边缘
然后输出

MATLAB进行边缘检测

我的问题是,在对中值滤波后的图像canny算子等进行边缘检测时,都是可行的
但是对滤波后转为二值化图像进行canny算子边缘检测时,却无法运行,错误原因如下
??? Error using ==> iptcheckinput
Function EDGE expected its first input, I,
to be one of these types:
double, single, uint8, uint16, uint32, int8, int16,
int32
Instead its type was logical.
Error in ==> edge>parse_inputs at 564
iptcheckinput(I,'numeric','nonsparse','2d',mfilename,'I',1);
Error in ==> edge at 197
[a,method,thresh,sigma,thinning,H,kx,ky] =
parse_inputs(varargin:);

请问各位高手,这是什么原因呢?帮忙解决下,非常感谢
以下是我的程序

I=imread('zhou.tif');
I1=rgb2gray(I);%将真彩图像转换为灰度图像
subplot(221);imshow(I1);title('灰度化图像');
%以下代码将进行滤波处理
I2=medfilt2(I1,[7 7]);%进行7*7模板的中值滤波
subplot(222);imshow(I2);title('7*7模板中值滤波');
%进行二值化
BW=im2bw(I2,0.95);
subplot(223);imshow(BW);title('二值化图像');
%进行边缘检测
BW1=edge(BW,'canny');
subplot(224);imshow(BW1);title('canny算子检测图像');

参考技术A I1=rgb2gray(I);%将真彩图像转换为灰度图像
这句话错了,I不是rgb图象,不能使用这个函数.
参考技术B 问专业人士

以上是关于Matlab边缘检测问题的主要内容,如果未能解决你的问题,请参考以下文章

matlab 图像边缘检测

图像边缘检测基于matlab灰度图像的积累加权边缘检测含Matlab源码 2010期

图像的亚像素边缘检测 MATLAB代码

MATLAB 图象去噪 边缘检测

边缘检测基于matlab八方向sobel图像边缘检测含Matlab源码 1865期

图像边缘检测基于matlab Zernike矩亚像素边缘检测含Matlab源码 1536期