基础版图像处理小工具,完成图像处理的基本操作和阐述其原理。
通过uigetfile打开文件选择对话框获取图像,axes();imshow()将图像显示到窗口。
% --- 载入图像
function btn1_Callback(hObject, eventdata, handles)
%打开文件选择对话框,并返回选择文件的名称和路径(image=[path file])
[file path]=uigetfile({'*.jpg';'*.bmp';'*.jpeg';'*.png'}, '打开文件');
image=[path file];
handles.file=image;
if (file==0)
warndlg('请选择一张图片...') ; %未选择图片出现提示
end
%获取图像
handles.img=imread(image);
%创建加载等待条对话框
h = waitbar(0,'等待...');
steps = 100;
for step = 1:steps
waitbar(step / steps)
end
%关闭对话框
close(h)
%显示图像到窗口,清除坐标区
axes(handles.img1);
cla;
imshow(handles.img);
axes(handles.img2);
cla;
imshow(handles.img);
axes(handles.img3);
cla;
imshow(handles.img);
axes(handles.img4);
cla;
imshow(handles.img);
%guidata(obj,data) 将指定的数据存储在其应用程序数据中
guidata(hObject,handles);
分析:
回调函数中主要用到的函数:
[file path]=uigetfile()——打开文件选择对话框,返回选择文件的名称和路径
warndlg(‘请选择一张图片…’)——创建警告对话框
waitbar(0,‘等待…’)——创建加载等待条对话框
axes(handles.img1);
imshow(handles.img)——显示图像到窗口
guidata(obj,data)——将指定的数据存储在其应用程序数据中
set(handles.btn2,‘Enable’,‘on’)——载入图像以后启用其他按钮
彩色图像一般具有三通道,每个像素由R、G、B三个分量表示,每个通道取值范围0-255。灰度图像每个像素只有一个采样颜色的图像,这类图像通常显示为从最暗黑色到最亮的白色的灰度。灰度值分布在0-255之间。彩色图像灰度化的方法有:
最大值法:使R,G,B的值等于3值中最大的一个,R=G=B=max(R,G,B),最大值法会形成亮度很高的灰度图像。
平均值法:是R,G,B的值求出平均值,R=G=B=(R+G+B)/3,平均值法会形成较柔和的灰度图像。
加权平均值法:根据重要性或其他指标给R,G,B赋予不同的权值,并使R,G,B的值加权平均,R=G=B=WR+VG+UB,W,V,U分别表示权重
本模块使用的函数rgb2gray(I)用到的算法是加权平均法。
% --- 灰度化
function btn5_Callback(hObject, eventdata, handles)
%将原图像变成灰度图
handles.grayimg = rgb2gray(handles.img);
%输出灰度图到窗口
axes(handles.img2);
imshow(handles.grayimg);
set(handles.t1,'String',"加权平均值灰度化");
二值图像指矩阵中只有0和1的图像。
BW = im2bw(I,level) 将灰度图像 I 转换为二值图像 BW,方法是将输入图像中亮度大于 level 的所有像素替换为值 1(白色),将所有其他像素替换为值 0(黑色)。
% --- 二值化
function btn6_Callback(hObject, eventdata, handles)
%将原图像变成灰度图
handles.grayimg = rgb2gray(handles.img);
I = get(handles.btn6,'Value');
handles.binarize = im2bw(handles.grayimg,I);
%输出灰度图到窗口
axes(handles.img2);
imshow(handles.binarize);
set(handles.log_btn6,'String',I);
set(handles.t1,'String',"阈值为"+I+"的二值化");
将两个图像的像素值相加,得到一张叠加图像,用imadd()实现算法。
% --- 图像叠加
function btn7_Callback(hObject, eventdata, handles)
%打开文件选择对话框,并返回选择文件的名称和路径(image=[path file])
[file1 path1]=uigetfile({'*.jpg';'*.bmp';'*.jpeg';'*.png'}, '打开文件');
image1=[path1 file1];
handles.file1=image1;
if (file1==0)
warndlg('请选择一张图片...') ; %未选择图片出现提示
end
%获取图像
handles.image1=imread(image1);
%创建加载等待条对话框
h = waitbar(0,'等待...');
steps = 100;
for step = 1:steps
waitbar(step / steps)
end
%关闭对话框
close(h)
%显示图像到窗口2,清除坐标区
axes(handles.img2);
cla;
%获取第一张图像的大小
[a,b,c]=size(handles.img);
%设置第二张图像大小
handles.image1 = imresize(handles.image1,[a b]);
%显示第二张图像
imshow(handles.image1);
set(handles.t1,'String',"相加图片");
%用imadd()函数将两图像相加
handles.addimg = imadd(handles.img,handles.image1);
%输出结果
axes(handles.img3);
cla;
imshow(handles.addimg);
set(handles.t2,'String',"相加结果");
分析:图像叠加比较容易让图像亮度偏大,因为单纯的将像素值相加,结果图像的像素值比两张原图像的值都要大,有时候会使图像曝光度过大,失去原来的信息
在前一张图像的像素点上减去后一张的像素值,得到一张相减图像,用imsubtract()实现算法。
% --- 目标检测
function btn8_Callback(hObject, eventdata, handles)
[file2 path2]=uigetfile({'*.jpg';'*.bmp';'*.jpeg';'*.png'}, '打开文件');
image2=[path2 file2];
handles.file2=image2;
if (file2==0)
warndlg('请选择一张图片...') ; %未选择图片出现提示
end
%获取图像
handles.image2=imread(image2);
%创建加载等待条对话框
h = waitbar(0,'等待...');
steps = 100;
for step = 1:steps
waitbar(step / steps)
end
%关闭对话框
close(h)
%显示图像到窗口2,清除坐标区
axes(handles.img2);
cla;
%获取第一张图像的大小
[a,b,c]=size(handles.img);
%设置第二张图像大小
handles.image2 = imresize(handles.image2,[a b]);
%显示第二张图像
imshow(handles.image2);
set(handles.t1,'String',"相减图片");
%imsubtract()函数将两图像相减
handles.imsub=imsubtract(handles.img,handles.image2);
%输出结果
axes(handles.img3);
cla;
imshow(handles.imsub);
set(handles.t2,'String',"相减结果");
分析:两图像相减时,相当于做减操作的图像作为模板,加深被减图像相应位置的颜色。做减操作的图像的像素值在被减图像上减去,降低了相应位置的像素值,使图像相应位置变暗。
灰度变换分为线性变换和非线性变换,其中非线性变换有指数变换和对数变换。在本模块中设置了三种类型的灰度变换:
(1).线性变换:g(x,y)=f(x,y)*tana;
(2) 指数变换:g(x,y)=f(x,y)^r
(3).对数变换:g(x,y)=loga(f(x,y))=log(f(x,y))/loga
% --- a1:线性变换
function a1_Callback(hObject, eventdata, handles)
%将图像化为灰度图并设为双精度
handles.gray = im2double(rgb2gray(handles.img));
%通过滑块获取线性变换的tan值
tan = get(handles.a1,'Value');
tan = tan*0.1;
set(handles.log_a1,'String',num2str(tan));
%设置与img大小相同的矩阵
[m,n] = size(handles.gray);
handles.img_a1 = zeros(m,n);
for i=1:m
for j = 1:n
handles.img_a1(i,j)=handles.gray(i,j)*tan;
%线性变换公式:g(x,y)=f(x,y)*tan
end
end
%输出结果
axes(handles.img2);
cla;
imshow(handles.img_a1);
set(handles.t1,'String',"线性变换 tana="+tan);
% --- a2:指数变换
function a2_Callback(hObject, eventdata, handles)
%将图像化为灰度图并设为双精度
handles.gray= im2double(rgb2gray(handles.img));
%通过滑块获取指数变换的r
r = get(handles.a2,'Value');
r = exp(r);
set(handles.log_a2,'String',num2str(r));
%设置与img大小相同的矩阵
[m,n] = size(handles.gray);
handles.img_a2 = zeros(m,n);
for i=1:m
for j = 1:n
handles.img_a2(i,j)=handles.gray(i,j)^r;
%指数变换公式:g(x,y)=f(x,y)^r
end
end
%输出结果
axes(handles.img3);
cla;
imshow(handles.img_a2);
set(handles.t2,'String',"指数变换 r="+r);
% --- a3:对数变换
function a3_Callback(hObject, eventdata, handles)
%将图像化为灰度图并设为双精度
handles.gray= im2double(rgb2gray(handles.img));
%通过滑块获取对数变换的a
a = get(handles.a3,'Value');
set(handles.log_a3,'String',num2str(a));
%设置与img大小相同的矩阵
[m,n] = size(handles.gray);
handles.img_a3 = zeros(m,n);
for i=1:m
for j = 1:n
handles.img_a3(i,j)=log(handles.gray(i,j)+1)/a;
%对数变换公式:g(x,y)=log(f)/log(a)
end
end
%输出结果
axes(handles.img4);
cla;
imshow(handles.img_a3);
set(handles.t3,'String',"对数变换 a="+a);
线性变换
当tana小于1时,图像灰度范围被压缩,图像变暗;
当tana等于1时,图像灰度范围无变化,图像不变;
当tana大于1时,图像灰度范围被拉伸,图像变亮;
指数变换
当r小于1时,提高灰度级,图像变亮;
当r等于1时,图像不变;
当r大于1时,降低灰度级,图像变暗;
对数变换
当loga小于1时,提高灰度级,图像变亮;
当loga等于1时,图像不变;
当loga大于1时,降低灰度级,图像变暗;
(1).直方图:直方图有两种定义,一是h(rk)=nk,nk指灰度级为rk的像素总数;二是p(rk)=nk/n,其中n指图像中的像素总个数。第二种定义体现了灰度级在图像中所占的比例,p(rk)的值也规定在了0到1之间。
(2).直方图均衡化:将图像中像素个数多的灰度级进行展宽,像素个数少的灰度级进行缩减。
(3).原理:得到图像每一个灰度级rk在图像中的比重p(rk),将比重累积Sum(rk),每一次累积的结果乘灰度级得到当前灰度级变换后的灰度级sk,将变换后灰度级相等的灰度级比重相加,得到变换后的新的灰度级比重P(sk)。P(Sk)即是直方图均衡化的结果。
% --- 直方图均衡化
function btn9_Callback(hObject, eventdata, handles)
%获得原图像直方图
[m,n,o] = size(handles.img);
%获取图像大小参数
hist = zeros(1,256);
% 创建1个1X256的全0矩阵;
for i = 1:256
hist(i)=length(find(handles.img==(i-1)))/(m*n);
end
%find(X) 返回一个包含数组 X 中每个非零元素的线性索引的向量。
%length()返回数组长度大小
%hist(i)返回相同灰度像素占总像素个数的比重
axes(handles.img2);
cla;
bar(0:255,hist);
set(handles.t1,'String',"原图像直方图");
%均衡化处理
s1 = zeros(1,256);
s2= zeros(1,256);
temp=0;
for i=1:256
temp = temp+hist(i);
s1(i)=temp;
end
%计算sum nk
% i == rk(灰度级) hist(i)==p(rk)(灰度级比重) s1(i)==Prk累积
s2 =round(s1*255); %乘以255.在向下取整
% s2==Sk(均衡后图像每个像素新的灰度级)
newhist=zeros(1,256);
for i=1:256
newhist(i)=sum(hist(find(s2==(i-1))));
end
handles.newimg=handles.img;
for i =1:256
handles.newimg(find(handles.img==(i-1)))=s2(i);
end
%把之前灰度的矩阵映射到对应灰度,即用s2中的灰度代替
axes(handles.img3);
cla;
imshow(handles.newimg);
set(handles.t2,'String',"均衡化图像");
axes(handles.img4);
cla;
bar(0:255,newhist)
set(handles.t3,'String',"均衡化直方图");
分析:当图像的灰度级将击中集中在某一个比较小的范围内,图像将会过于暗或过于亮,这种时候,有很大的灰度级没有被利用,图像的信息仅靠一部分灰度级展示,对比度并不强,这是我们就需要利用直方图均衡化使原图像的直方图均匀分布,从而增加图像的整体对比度。
高斯噪声:使用imnoise(handles.img,“gaussian”)函数为图像添加高斯噪声
椒盐噪声:使用imnoise(handles.img,“salt & pepper”)函数为图像添加椒盐噪声
三种滤波器的原理:
(1).均值滤波器:某一像素为中心,将中心点邻域内所有像素点的均值代替中心像素点的值
(2).中值滤波器:某一像素为中心,将中心点邻域内所有像素点的灰度级按照大小顺序排序,取中值代替中心点的值
(3).高斯滤波器:某一像素为中心,将中心点邻域内所有像素点的灰度按照高斯正态分布曲线统计并分配权值,然后将邻域内所有点的加权平均值代替中心点的值
% --- b1:均值滤波
function b1_Callback(hObject, eventdata, handles)
handles.noise=rgb2gray(handles.noise);
[p,q] = size(handles.noise); %获取图像大小
handles.Meanimg = uint8(zeros(p+2,q+2));
%待处理矩阵,初始为uint8类型全0矩阵,大小为原始矩阵再加一圈长度为1的外围边框,
for i=1:p
for j =1:q
handles.Meanimg(i+1,j+1) = handles.noise(i,j);
end
end
handles.mean = handles.Meanimg; %均值处理矩阵
%为待处理矩阵赋值
handles.derta = zeros(3,3); %3阶模板矩阵
%遍历处理矩阵像素
for i = 2:p+1
for j = 2:q+1
handles.derta(1,1) = handles.Meanimg(i-1,j-1); %左上
handles.derta(1,2) = handles.Meanimg(i-1,j); % 左
handles.derta(1,3) = handles.Meanimg(i-1,j+1); %左下
handles.derta(2,1) = handles.Meanimg(i,j-1); %下
handles.derta(2,2) = handles.Meanimg(i,j); % 当前
handles.derta(2,3) = handles.Meanimg(i,j+1);
handles.derta(3,1) = handles.Meanimg(i+1,j-1);
handles.derta(3,2) = handles.Meanimg(i+1,j);
handles.derta(3,3) = handles.Meanimg(i+1,j+1);
handles.mean(i,j) = round(mean(mean(handles.derta)));%均值滤波
end
end
%通过循环遍历的方法,将原图像的像素值及其八邻接区域的值赋给模板矩阵derta
%填充好derta的值后,根据均值滤波求均值的函数进行求值,将结果传给mean矩阵
%一个循环结束后开始检索并计算下一个像素点
%函数调用输出结果
handles.noiseMean = uint8(zeros(p,q));
for i = 1:p
for j = 1:q
handles.noiseMean(i,j) = handles.mean(i+1,j+1);%均值滤波处理结果
end
end
%输出结果
axes(handles.img2);
cla;
imshow(handles.noiseMean);
set(handles.t1,'String',"均值滤波处理结果");
% --- b2:中值滤波
function b2_Callback(hObject, eventdata, handles)
%将原图像的
a = handles.noise(:,:,1);
b = handles.noise(:,:,2);
c = handles.noise(:,:,3);
handles.Med1=medfilt2(a); %中值滤波3x3模板
handles.Med2=medfilt2(b);
handles.Med3=medfilt2(c);
handles.noiseMed=cat(3,handles.Med1,handles.Med2,handles.Med3);
%输出结果
axes(handles.img3);
cla;
imshow(handles.noiseMed);
set(handles.t2,'String',"中值滤波处理结果");
% --- b3:高斯滤波
function b3_Callback(hObject, eventdata, handles)
h=fspecial('gaussian',[8 8],1.7);
handles.noiseGau=imfilter(handles.noise,h,'replicate');
%输出结果
axes(handles.img4);
cla;
imshow(handles.noiseGau);
set(handles.t3,'String',"高斯滤波处理结果");
均值滤波和和中值滤波都可以起到平滑图像,虑去噪声的功能。
均值滤波采用线性的方法,平均整个窗口范围内的像素值,均值滤波不能很好地保护图像细节,在图像去噪的同时也破坏了图像的细节部分,从而使图像变得模糊,不能很好地去除噪声点。均值滤波对高斯噪声表现较好,对椒盐噪声表现较差。
中值滤波采用非线性的方法,它可以保护图像尖锐的边缘,选择适当的点来替代污染点的值,所以对椒盐噪声表现较好,对高斯噪声表现较差。
高斯滤波处理椒盐噪声和高斯噪声都有一定的效果。处理情况复杂的数据集时,能够更好的保留图像分布特点。如果需要针对固定特点的图像进行处理,还是会选择均值滤波处理高斯噪声,中值滤波处理椒盐噪声。
如果要对彩色图像进行平滑处理,可以通过将三个通道的图像分别进行平滑处理,然后再将单通道图合成。
空域提取边缘可以用一阶算子和二阶算子,一阶算子有:梯度算子、Robert算子,sobel算子、prewitt算子。二阶有laplace算子。本模块着重使用Robert算子,sobel算子、laplace算子进行验证。
Robert算子:G[F(x,y)]=|F(x,y)−F(x+1,y)|+|F(x,y)−F(x,y+1)|
sobel算子:
S(x)=
|f(x-1,y+1)+2f(x,y+1)+f(x+1,y+1)|-|f(x-1,y-1)+2f(x,y-1)-f(x+1,y-1)|
S(y)=
|f(x+1,y-1)+2f(x+1,y)+f(x+1,y+1)|-|f(x-1,y-1)+2f(-1x,y)-f(x-1,y+1)|
G=|S(x)|+|S(y)|
laplace算子:▽²f=f(x+1,y)+f(x-1,y)+f(x,y+1)+f(x,y-1)+4*f(x,y)
% --- c1:robert提取边缘
function c1_Callback(hObject, eventdata, handles)
[m,n]=size(handles.img);
handles.edge_la = uint8(zeros(m,n));%直接忽略边界,将结果类型强制转换为uint8
for i = 1 : m - 1
for j = 1 : n - 1
handles.edge_ro(i, j) = uint8(abs(handles.img(i, j) - handles.img(i + 1, j)) + abs(handles.img(i, j ) - handles.img(i, j + 1)));
end
end
%上述循环完成遍历加运算过程
%G[F(x,y)]=|F(x,y)−F(x+1,y)|+|F(x,y)−F(x,y+1)|
%输出结果
axes(handles.img2);
cla;
imshow(handles.edge_ro);
set(handles.t1,'String',"robert提取边缘");
% --- c2:laplace提取边缘
function c2_Callback(hObject, eventdata, handles)
[m,n]=size(handles.img)
handles.edge_la = uint8(zeros(m,n));
l = [0, 1, 0; 1, -4, 1; 0, 1, 0]; %3x3模板
for i = 2 : m - 1
for j = 2 : n - 1
sub = double(handles.img(i - 1 : i + 1, j - 1 : j + 1));
d = sum(sum(sub .* l));
% sum是对列向量求和,因为求和目标是二维矩阵,所以使用两次
handles.edge_la(i, j) = uint8(d);
end
end
%输出结果
axes(handles.img4);
cla;
imshow(handles.edge_la);
set(handles.t3,'String',"laplace提取边缘");
% --- c3:sobel边缘提取
function c3_Callback(hObject, eventdata, handles)
handles.img=medfilt2(handles.img);
[m,n]=size(handles.img);
handles.edge_so = uint8(zeros(m,n));%直接忽略边界,将结果类型强制转换为uint8
for i = 2 : m - 1
for j = 2 : n - 1
Sx=abs(handles.img(i-1,j+1)+2*handles.img(i,j+1)+handles.img(i+1,j+1))...
-abs(handles.img(i-1,j-1)+2*handles.img(i,j-1)+handles.img(i+1,j-1));
Sy=abs(handles.img(i+1,j-1)+2*handles.img(i+1,j)+handles.img(i+1,j+1))...
-abs(handles.img(i-1,j-1)+2*handles.img(i-1,j)+handles.img(i-1,j+1));
handles.edge_so(i, j)=abs(Sx)+abs(Sy);
end
end
%上述循环完成遍历加运算过程
%S(x)=
%|f(x-1,y+1)+2f(x,y+1)+f(x+1,y+1)|-|f(x-1,y-1)+2f(x,y-1)-f(x+1,y-1)|
%S(y)=
%|f(x+1,y-1)+2f(x+1,y)+f(x+1,y+1)|-|f(x-1,y-1)+2f(x-1,y)-f(x-1,y+1)|
%G=|S(x)|+|S(y)|
%输出结果
axes(handles.img3);
cla;
imshow(handles.edge_so);
set(handles.t2,'String',"sobel提取边缘");
图像的频率域处理:图像的频率域与图像的空间域具有一定的对应关系。低频率对应图像变化较慢的分量,如图像的平滑部分;高频率对应图像变化较快的分量,如图像的边缘或噪声。利用图像频率成分和图像内容的对应关系,可以将一些操作在频率域中做处理。在实际操作中,我们通常将傅里变换后的频谱图进行频谱中心化,这样使在四角的低频分量集中到中心的位置。这样利于处理
低通滤波:使低频通过而使高频衰减的滤波。高频衰减对应边缘等尖锐部分的信息被模糊掉,突出了图像的平滑部分。低通滤波结果:模糊
高通滤波:使高频通过而使低频衰减的滤波,低频衰减对应忽略掉平滑部分的图像信息,从而突出图像的边缘部分。高通滤波结果:锐化
% --- d1:添加高斯噪声
function d1_Callback(hObject, eventdata, handles)
handles.noise=imnoise(handles.img,"gaussian");
%输出结果
axes(handles.img1);
cla;
imshow(handles.noise);
set(handles.textn,'String',"添加高斯噪声");
guidata(hObject,handles);
% ---d2:添加椒盐噪声
function d2_Callback(hObject, eventdata, handles)
handles.noise=imnoise(handles.img,"salt & pepper");
%输出结果
axes(handles.img1);
cla;
imshow(handles.noise);
set(handles.textn,'String',"添加椒盐噪声");
guidata(hObject,handles);
% ---e1:理想低通滤波器
function e1_Callback(hObject, eventdata, handles)
handles.img=im2double(handles.img); %转换为double型方便后面的计算0
M=2*size(handles.img,1);
N=2*size(handles.img,2);
u=-M/2:(M/2-1);
v=-N/2:(N/2-1);
[U,V]=meshgrid(u,v); %后面将中心作为滤波器原点
D=sqrt(U.^2+V.^2); %计算每个点距离原点的距离。
D0=get(handles.se1,'Value'); %截止频率据原点的距离
H1=double(D<=D0); %构造理想低通滤波器
J1=fftshift(fft2(handles.img,size(H1,1),size(H1,2))); %转换到频域
K1=J1.*H1; %滤波处理
handles.X0=ifft2(ifftshift(K1)); %傅立叶反变换
handles.X0=handles.X0(1:size(handles.img,1),1:size(handles.img,2)); %改变图像大小
D0 = get(handles.se1,'Value');
set(handles.log_e1,'String',"D0="+num2str(D0));
%输出结果
axes(handles.img2);
cla;
imshow(handles.X0);
set(handles.t1,'String',"D0="+num2str(D0)+"理想低通滤波");
% --- e2:巴特沃斯低通滤波器
function e2_Callback(hObject, eventdata, handles)
handles.img=im2double(handles.img); %转换为double型方便后面的计算0
M=2*size(handles.img,1); %滤波器行数
N=2*size(handles.img,2); %滤波器列数 后面将中心作为滤波器原点
u=-M/2:(M/2-1);
v=-N/2:(N/2-1); %将滤波器的坐标值从(1:2M;1:2N)变为(-M/2:(M/2-1);-N/2:(N/2-1))这样做的目的在于将中心左边变为(0,0)
[U,V]=meshgrid(u,v); %使用向量 x 定义的 x 坐标和向量 y 定义的 y 坐标创建二维网格坐标。
D=sqrt(U.^2+V.^2); %计算每个点距离原点的距离。
D0=get(handles.se1,'Value'); %截止频率据原点的距离
n=6; %阶数
H=1./(1+(D./D0).^(2*n)); %构造巴特沃斯低通滤波器
J=fftshift(fft2(handles.img,size(H,1),size(H,2))); %转换到频域
K=J.*H; %滤波处理
handles.L0=ifft2(ifftshift(K)); %傅立叶反变换
handles.L0=handles.L0(1:size(handles.img,1),1:size(handles.img,2)); %改变图像大小
set(handles.log_e1,'String',"D0="+num2str(D0));
%输出结果
axes(handles.img3);
cla;
imshow(handles.L0);
set(handles.t2,'String',"D0="+num2str(D0)+"巴特沃斯低通滤波");
% --- e3:高斯低通滤波器
function e3_Callback(hObject, eventdata, handles)
handles.img=im2double(handles.img); %转换为double型方便后面的计算0
M=2*size(handles.img,1); %滤波器行数
N=2*size(handles.img,2); %滤波器列数 后面将中心作为滤波器原点
u=-M/2:(M/2-1);
v=-N/2:(N/2-1); %将滤波器的坐标值从(1:2M;1:2N)变为(-M/2:(M/2-1);-N/2:(N/2-1))这样做的目的在于将中心左边变为(0,0)
[U,V]=meshgrid(u,v); %使用向量 x 定义的 x 坐标和向量 y 定义的 y 坐标创建二维网格坐标。
D=sqrt(U.^2+V.^2); %计算每个点距离原点的距离。
D0=get(handles.se1,'Value'); %截止频率据原点的距离
h = -(D.^2)./(2*(D0^2));
H = exp(h); %构造高斯低通滤波器
J=fftshift(fft2(handles.img,size(H,1),size(H,2))); %转换到频域
K=J.*H; %滤波处理
handles.L0=ifft2(ifftshift(K)); %傅立叶反变换
handles.L0=handles.L0(1:size(handles.img,1),1:size(handles.img,2)); %改变图像大小
set(handles.log_e1,'String',"D0="+num2str(D0));
%输出结果
axes(handles.img4);
cla;
imshow(handles.L0);
set(handles.t3,'String',"D0="+num2str(D0)+"高斯低通滤波");
% --- e4:理想高通滤波器
function e4_Callback(hObject, eventdata, handles)
handles.img=im2double(handles.img); %转换为double型方便后面的计算0
M=2*size(handles.img,1);
N=2*size(handles.img,2);
u=-M/2:(M/2-1);
v=-N/2:(N/2-1);
[U,V]=meshgrid(u,v); %后面将中心作为滤波器原点
D=sqrt(U.^2+V.^2); %计算每个点距离原点的距离。
D0=get(handles.se2,'Value'); %截止频率据原点的距离
H1=double(D>=D0); %构造理想高通滤波器
J1=fftshift(fft2(handles.img,size(H1,1),size(H1,2))); %转换到频域
K1=J1.*H1; %滤波处理
handles.X0=ifft2(ifftshift(K1)); %傅立叶反变换
handles.X0=handles.X0(1:size(handles.img,1),1:size(handles.img,2)); %改变图像大小
D0 = get(handles.se2,'Value');
%输出结果
axes(handles.img2);
cla;
imshow(handles.X0);
set(handles.t1,'String',"D0="+num2str(D0)+"理想高通滤波");
% --- e5:巴特沃斯高通滤波器
function e5_Callback(hObject, eventdata, handles)
handles.img=im2double(handles.img); %转换为double型方便后面的计算0
M=2*size(handles.img,1); %滤波器行数
N=2*size(handles.img,2); %滤波器列数 后面将中心作为滤波器原点
u=-M/2:(M/2-1);
v=-N/2:(N/2-1); %将滤波器的坐标值从(1:2M;1:2N)变为(-M/2:(M/2-1);-N/2:(N/2-1))这样做的目的在于将中心左边变为(0,0)
[U,V]=meshgrid(u,v); %使用向量 x 定义的 x 坐标和向量 y 定义的 y 坐标创建二维网格坐标。
D=sqrt(U.^2+V.^2); %计算每个点距离原点的距离。
D0=get(handles.se2,'Value'); %截止频率据原点的距离
n=6; %阶数
H=1-(1./(1+(D./D0).^(2*n))); %构造巴特沃斯高通滤波器
J=fftshift(fft2(handles.img,size(H,1),size(H,2))); %转换到频域
K=J.*H; %滤波处理
handles.L0=ifft2(ifftshift(K)); %傅立叶反变换
handles.L0=handles.L0(1:size(handles.img,1),1:size(handles.img,2)); %改变图像大小
D0 = get(handles.se2,'Value');
%输出结果
axes(handles.img3);
cla;
imshow(handles.L0);
set(handles.t2,'String',"D0="+num2str(D0)+"巴特沃斯高通滤波");
% --- e6:高斯高通滤波器
function e6_Callback(hObject, eventdata, handles)
handles.img=im2double(handles.img); %转换为double型方便后面的计算0
M=2*size(handles.img,1); %滤波器行数
N=2*size(handles.img,2); %滤波器列数 后面将中心作为滤波器原点
u=-M/2:(M/2-1);
v=-N/2:(N/2-1); %将滤波器的坐标值从(1:2M;1:2N)变为(-M/2:(M/2-1);-N/2:(N/2-1))这样做的目的在于将中心左边变为(0,0)
[U,V]=meshgrid(u,v); %使用向量 x 定义的 x 坐标和向量 y 定义的 y 坐标创建二维网格坐标。
D=sqrt(U.^2+V.^2); %计算每个点距离原点的距离。
D0=get(handles.se2,'Value'); %截止频率据原点的距离
h = -(D.^2)./(2*(D0^2));
H =1- exp(h); %构造高斯高通滤波器
J=fftshift(fft2(handles.img,size(H,1),size(H,2))); %转换到频域
K=J.*H; %滤波处理
handles.L0=ifft2(ifftshift(K)); %傅立叶反变换
handles.L0=handles.L0(1:size(handles.img,1),1:size(handles.img,2)); %改变图像大小
D0 = get(handles.se2,'Value');
%输出结果
axes(handles.img4);
cla;
imshow(handles.L0);
set(handles.t3,'String',"D0="+num2str(D0)+"高斯高通滤波");
function se1_Callback(hObject, eventdata, handles)
D0 = get(handles.se1,'Value');//D0传值
set(handles.log_e1,'String',"D0="+num2str(D0));
function se2_Callback(hObject, eventdata, handles)
D0 = get(handles.se2,'Value');
set(handles.log_e2,'String',"D0="+num2str(D0));
分析:
理想低通滤波“截断”傅里叶变换中所有高频部分,但是理想低通滤波非常不实用,在使用中会产生“振铃”现象
巴特沃思滤波器的振铃现象比较不明显。通常很微小,但阶数增高的时候振铃变会成为一个重要的影响因素。随着阶数的增大,振铃现象将会越来越明显。
高斯滤波器的参数 D0 决定了平滑程度,D0越大,平滑程度就越好。因为噪声主要集中在高频段,所以通过高斯低通滤波器可以滤除噪声信息、平滑图像,但与此同时会滤除图像的细节信息,使图像变得模糊。
高通滤波器:在频域上对图像进行锐化处理效果很好,其中理想高通滤波器的振铃现象依旧明显,巴特沃斯滤波器振铃现象相较理想高通不明显,高斯高通滤波器锐化效果很好。三种滤波器在对图像处理使,随着D0的增大,图像的颜色将变暗。
图像退化:成像过程中的“退化”,指成像系统各种因素的影响,使图像质量降低。一般的图像退化模型可表示为
*g(x,y)=f(x,y)h(x,y)+n(x,y)
其中:g(x,y)-退化后的图像,f(x,y)-原图像,h(x,y)-退化函数,n(x,y)-噪声
图像复原:图像退化的逆过程,将退化的过程加以估计,建立退化数学模型,补偿退化过程造成的失真。
空间滤波:这类滤波适合没有退化函数,图像中只存在噪声这一个影响因素的情况,去除噪声的空间滤波可以有中值滤波,均值滤波等,这里只讨论基于运动模糊的图像复原,不做过多赘述。
逆滤波复原:当不考虑噪声,只有退化函数h(x,y)时,图像退化模型可表示为g(x,y)=f(x,y)*h(x,y),可以得出原图像为:f(x,y)=g(x,y)/h(x,y)。也就是说,如果已知退化图像和退化函数,当噪声为0时,我们可以通过傅里叶逆变换得到复原图像。在有噪声的情况下,逆滤波原理式为:f(x,y)=g(x,y)/h(x,y)-n(x,y)/h(x,y).
维纳滤波复原:维纳滤波综合考虑了退化函数和噪声对图像的影响。维纳滤波中考虑了考虑了模糊函数、噪声、模糊图像中噪声比率、图像和噪声自相关性等因素。能够将添加了噪声的模糊图像更好的复原.
% --- f3.运动模糊
function f3_Callback(hObject, eventdata, handles)
PSF=fspecial ('motion',25,11); %运动模糊函数,运动位移为25像素,角度为11
handles.noise=imfilter (handles.img,PSF, 'conv' , 'circular') ; %对图像做运动模糊处理
guidata(hObject,handles);
%输出结果
axes(handles.img2);
cla;
imshow(handles.noise);
set(handles.t1,'String',"无噪音运动模糊图像");
% ---f1:加噪声运动模糊
function f1_Callback(hObject, eventdata, handles)
PSF=fspecial ('motion',25,11); %运动模糊函数,运动位移为25像素,角度为11
Blurred=imfilter (handles.img,PSF, 'conv' , 'circular') ; %对图像做运动模糊处理
handles.noise=imnoise(Blurred,'gauss',0.02); %添加高斯噪音
guidata(hObject,handles);
%输出结果
axes(handles.img2);
cla;
imshow(handles.noise);
set(handles.t1,'String',"有噪音运动模糊图像");
% ---f2:图像复原
function f2_Callback(hObject, eventdata, handles)
PSF=fspecial ('motion',25,11); %运动模糊函数,运动位移为25像素,角度为11
%维纳滤波
q=abs(fft2(handles.noise)).^2; %噪声功率谱
q1=sum(q(:))/numel(handles.noise);%噪声平均功率
q2=abs(fft2(handles.img)).^2; %图像功率谱
q3=sum(q2(:))/numel(handles.img); %图像平均功率
NSR=q1/q3; %计算噪声和信号比率
NCORR=fftshift(real(ifft2(q))); %噪声自相关函数
ICORR=fftshift(real(ifft2(q2))); %图像自相关函数
handles.a=deconvwnr (handles.noise, PSF); %只考虑模糊函数,不考虑噪声
handles.a1=deconvwnr(handles.noise,PSF,NSR); %考虑模糊图像中噪声比率
handles.a2=deconvwnr(handles.noise,PSF,NCORR,ICORR); %考虑图像中图像和噪声自相关性
%输出结果
axes(handles.img3);
cla;
imshow(handles.a);
set(handles.t2,'String',"不考虑噪声维纳滤波复原");
%输出结果
axes(handles.img4);
cla;
imshow(handles.a2);
set(handles.t3,'String',"考虑噪声维纳滤波复原");
分析:如果在使用维纳滤波进行图像复原的过程中,可以看到,不论图像是否添加噪音,如果在复原过程中不考虑噪声,噪声对图像的影响都将明显变大。当图像中有噪声而不考虑对噪声的处理时,在复原后,图像的噪声影响扩大,得不到正确的结果。
腐蚀:元素结构内有0,就将中心变为0,所以除非图像内部为1的像素点全部充满元素结构,像边界这种01分界点,为1的值极易被变为0,因而完成了图像的“腐蚀”
膨胀:在元素结构内遇到为1的像素,就将参考点变为1,如果在边界上,比如3x3矩阵元素结构的右下角像素值为1,而中心像素值为0,此时中心值将变为1,这样就相当于对图像完成了“膨胀”
开运算:先腐蚀后膨胀
闭运算:先膨胀后腐蚀
% --- g1:腐蚀
function g1_Callback(hObject, eventdata, handles)
handles.img = rgb2gray(handles.img);
handles.img = im2bw(handles.img,0.55);
if(handles.index==1)
helpdlg('未选择结构类型!','Morphological Operations');
end
if(handles.index==2) %菱形结构元素图像腐蚀
SE=strel("diamond",1);%创建一个菱形结构元素
handles.result = imerode(handles.img,SE);
end
if(handles.index==3) %矩形结构元素图像腐蚀
[h,w]=size(handles.img); %获取图像尺寸
handles.result=ones(h,w); %定义输出图像,初始化为1
for x=2:w-1
for y=2:h-1 %扫描图像每一点,即结构元素移动到每一个位置(x,y的坐标指的是结构元素参考点落在图像上的位置)
for m=-1:1
for n=-1:1 %当前点周围3×3范围,即3×3结构元素所覆盖范围
if handles.img(y+n,x+m)==0 %该范围内有像素点为0,即该位置不能完全包含结构元素
handles.result(y,x)=0; %将参考点记录为背景点,即腐蚀掉
break;
end
end
end
end
end
end
if(handles.index==4) %H形结构元素图像腐蚀
a = [1,0,1;1,1,1;1,0,1];
SE = strel('arbitrary', a);%创建一个H形结构元素
handles.result = imerode(handles.img,SE);
end
%输出结果
axes(handles.img1);
cla;
imshow(handles.result);
set(handles.textn,'String',handles.type+"结构元素腐蚀");
% --- g2:膨胀
function g2_Callback(hObject, eventdata, handles)
handles.img = rgb2gray(handles.img);
handles.img = im2bw(handles.img,0.55);
if(handles.index==1)
helpdlg('未选择结构类型!','Morphological Operations');
end
if(handles.index==2) %菱形结构元素图像膨胀
SE=strel("diamond",1);%创建一个菱形结构元素
handles.result = imdilate(handles.img,SE);
end
if(handles.index==3) %矩形结构元素图像膨胀
[h,w]=size(handles.img); %获取图像尺寸
handles.result=zeros(h,w); %定义输出图像,初始化为1
for x=2:w-1
for y=2:h-1 %扫描图像每一点,即结构元素移动到每一个位置(x,y的坐标指的是结构元素参考点落在图像上的位置)
for m=-1:1
for n=-1:1 %当前点周围3×3范围,即3×3结构元素所覆盖范围
if handles.img(y+n,x+m) %该范围内有像素点为0,即该位置不能完全包含结构元素
handles.result(y,x)=1; %将参考点记录为背景点,即膨胀
break;
end
end
end
end
end
end
if(handles.index==4) %H形结构元素图像膨胀
a = [1,0,1;1,1,1;1,0,1];
SE = strel('arbitrary', a);%创建一个H形结构元素
handles.result = imdilate(handles.img,SE);
end
%输出结果
axes(handles.img2);
cla;
imshow(handles.result);
set(handles.t1,'String',handles.type+"结构元素膨胀");
% --- g3:开运算
function g3_Callback(hObject, eventdata, handles)
handles.img = rgb2gray(handles.img);
handles.img = im2bw(handles.img,0.55);
if(handles.index==1)
helpdlg('未选择结构类型!','Morphological Operations');
end
%开运算先腐蚀再膨胀运算
if(handles.index==2) %菱形结构元素图像开运算
SE=strel("diamond",1);%创建一个菱形结构元素
handles.result=imdilate(imerode(handles.img,SE),SE);
end
if(handles.index==3) %矩形结构元素图像开运算
SE=strel("square",3) %创建一个宽度为5个像素的正方形结构元素
handles.result=imdilate(imerode(handles.img,SE),SE);
end
if(handles.index==4) %H形结构元素图像开运算
a = [1,0,1;1,1,1;1,0,1];
SE = strel('arbitrary', a);%创建一个H形结构元素
handles.result=imdilate(imerode(handles.img,SE),SE);
end
%输出结果
axes(handles.img3);
cla;
imshow(handles.result);
set(handles.t2,'String',handles.type+"结构元素开运算");
% --- g4:闭运算
function g4_Callback(hObject, eventdata, handles)
handles.img = rgb2gray(handles.img);
handles.img = im2bw(handles.img,0.55);
if(handles.index==1)
helpdlg('未选择结构类型!','Morphological Operations');
end
%闭运算先膨胀再腐蚀运算
if(handles.index==2) %菱形结构元素图像闭运算
SE=strel("diamond",1);%创建一个菱形结构元素
handles.result=imerode(imdilate(handles.img,SE),SE);
end
if(handles.index==3) %矩形结构元素图像闭运算
SE=strel("square",3) %创建一个宽度为5个像素的正方形结构元素
handles.result=imerode(imdilate(handles.img,SE),SE);
end
if(handles.index==4) %H形结构元素图像闭运算
a = [1,0,1;1,1,1;1,0,1];
SE = strel('arbitrary', a);%创建一个H形结构元素
handles.result=imerode(imdilate(handles.img,SE),SE);
end
%输出结果
axes(handles.img4);
cla;
imshow(handles.result);
set(handles.t3,'String',handles.type+"结构元素闭运算");
% ---p1:
function p1_Callback(hObject, eventdata, handles)
handles.index=get(hObject,'Value');
switch handles.index
case 1
helpdlg('请选择一种结构元素类型','Morphological Operations');
case 2
handles.type='diamond';
case 3
handles.type='square';
case 4
handles.type='H';
end
guidata(hObject,handles);
应用基于聚类的图像分割,将图像分割看作对像素进行分类的问题。将像素表示成特征空间的点,把这些点划分为不同的类别。实现对图像的分组,然后利用“连通成分标记”找到连通区域。
K均值聚类:先确定K个初始聚类中心,然后根据各类样本到聚类中心烦人距离平方和最小的准则。不断调整聚类中心,知道聚类合理。
% --- h1:检测红苹果
function h1_Callback(hObject, eventdata, handles)
hsv=rgb2hsv(handles.img); %将 RGB 颜色转换为 HSV
handles.h=hsv(:,:,1); %提取红色分量
handles.h(handles.h>330/360)=0; %将检测出来为苹果(红色)的部分的像素变为0
%输出结果
axes(handles.img2);
cla;
imshow(handles.h);
set(handles.t1,'String',"红色分量");
[N,M]=size(handles.h);
training=handles.h(:);
startdata = [0;60/360;120/360;180/360;240/360;300/360];
[IDX,C]= kmeans(training,6,'Start',startdata); %将将360划分为六个区间,确定初始聚类中心
idbw = (IDX == 1);
handles.template = reshape(idbw, size(handles.h));
%输出结果
axes(handles.img3);
cla;
imshow(handles.template);
set(handles.t2,'String',"分割后的图像");
图像分割:应用了基于最大类间方差法的阈值分割,将所有的像素分为两组,然后实现图像分割。其中,属于“同一类别”的类别必须具有较大的一致性,“不同类别”的对象具有较大的差异性。
硬币计数:检测分割后的图像的四连通区域,通过函数bwlabel对二维二值图像中的连通分量进行标注,即可计算图像中的硬币数量。
% --- h2:硬币检测
function h2_Callback(hObject, eventdata, handles)
handles.img=rgb2gray(handles.img);%转换为灰度图
a=graythresh(handles.img); %OTSU计算最佳阈值
handles.img1=im2bw(handles.img,a);%二值化提取特征
SE=strel("diamond",2); %创建一个菱形结构元素
handles.result1=imopen(imclose(handles.img1,SE),SE); %先闭后开
[L, num] = bwlabel(handles.result1, 4); %检测二值图像中四连通域的个数。
% BW 为输入二值化图像;
% NUM 为找到的连通区域数目;
% L 为输出图像矩阵,其元素值为整数,背景被标记为0,第一个连通区域被标记为1,第n个连通区域被标记为n
%输出结果
axes(handles.img2);
cla;
imhist(handles.img);
set(handles.t1,'String',"最佳阈值为"+a);
%输出结果
axes(handles.img3);
cla;
imshow(handles.img1);
set(handles.t2,'String',"先闭后开");
%输出结果
axes(handles.img4);
cla;
imshow(handles.result1);
set(handles.t3,'String',"检测到的硬币个数为:"+num);
最大类间方差法:该方法利用目标区域与背景区域之间的方差最大的思想,达到分割图像的目的。当选取最佳阈值a时,目标与背景之间的方差值最大,小于阈值a的区域为D1,大于阈值的区域为D2,将需要的区域区分开来。该方法在图像灰度直方图呈现单峰时效果较好。但图像在光照不均匀,噪声点大等情况下分割效果不佳。
图像分割:通过最优边缘检测提取图像的边界,canny算子可以尽可能多的检测出实际边缘。使检测的图像能够闭合。然后可以将这些形状进行闭运算填充一些比较小的洞,针对一些比较大的洞可以通过imfill函数进行填充。这样我们就可将图像处理成边界清晰且内外分明的图像,为后面检测圆形和矩形奠定了良好的基础。
% --- h3:检测圆和矩形
function h3_Callback(hObject, eventdata, handles)
handles.img=rgb2gray(handles.img);
handles.img = edge(handles.img,'canny'); %提取边界
SE=strel('disk',2);
handles.morph=imclose(handles.img,SE); %对图像执行闭运算(先膨胀后腐蚀)
handles.morph=imfill(handles.morph,'holes');%填充图像中的孔。
[B,L]=bwboundaries(handles.morph);%跟踪图像中对象的外边界,不包括些对象内部的孔洞的边界。
%B-边界像素的行和列坐标;L-标签矩阵
%输出结果
axes(handles.img2);
cla;
imshow(handles.img);
set(handles.t1,'String',"二值化");
%输出结果
axes(handles.img3);
cla;
imshow(handles.morph);
set(handles.t2,'String',"区域填充");
%输出结果
axes(handles.img4);
cla;
imshow(handles.morph);
set(handles.t3,'String',"检测圆和矩形");
STATS = regionprops(L,'Area', 'Centroid','BoundingBox');
%测量标注图像L中每个标注区域的属性(Area—区域中的实际像素数, Centroid—区域的质心(重心),BoundingBox—包含区域的最小外接框的位置和大小)
len=length(STATS); %遍历这些标注区域
hold on
for i=1:len
R=STATS(i).Area/(STATS(i).BoundingBox(3)*STATS(i).BoundingBox(4));
%区域的实际像素数/区域最小外接框面积
boundary=fliplr(B{i});
%fliplr:将数组从左向右翻转
%B{i}:数组元胞,包含了第i个区域对象的所有边界像素。元胞中还包含了每个边界像素的行列坐标
everylen=length(boundary);
%区域对象的周长
F=4*pi*STATS(i).Area/(everylen^2);
%通过F=4pi面积/周长的平方,判断区域对象形状
dis=pdist2(STATS(i).Centroid,boundary,'euclidean');
%区域的质心与区域的所边界像素之间的距离
miu=sum(dis)/everylen;
%miu=质心与边界的平均距离
sigma=sum((dis-miu).^2)/everylen;
%sigma标准差
C=miu/sigma;
%C-变异系数,衡量距离变异程度
%检测到矩形: R>0.9 && F<1
if R>0.9 && F<1
rectangle('Position',STATS(i).BoundingBox,'edgecolor','b','linewidth',2);
%在STATS(i).BoundingBox中创建一个矩形。颜色设为蓝色,线条宽度设为1
end
%检测到圆形: R>pi/4-0.1 && R<pi/4+0.1 && F>0.9 && C>10
if R>pi/4-0.1 && R<pi/4+0.1 && F>0.9 && C>10
rectangle('Position',[STATS(i).Centroid(1)-miu,STATS(i).Centroid(2)-miu,2*miu,2*miu],'Curvature',[1,1],'edgecolor','g','linewidth',2);
%在STATS(i).BoundingBox中创建一个矩形。'Curvature',[1,1]设置水平和垂直曲率的量,将矩形改变为圆形。颜色设为绿色,线条宽度设为1
end
end
hold off
分析:
形状检测:
在上述代码中,用了三种图形检测方法共同测定形状的类型;
1.区域的实际像素数/区域最小外接框面积
通过计算可知圆的面积pirr与最小外接框的面积(2r)^2的比值为pi/4,约等于0.78左右,而矩形则为1。
2.通过圆形度公式R0=4pi*S/(L^2),判断区域对象形状
R0的取值再0-1之间,当R0越接近1,该形状就越接近圆形。通常规定0.5-0.9为椭圆,0.9~1为圆
3.通过质心到边界距离的变异系数判定形状。变异系数越小,重心与边界每个点的距离变化程度越小,代码中用了变异系数的倒数,因此倒数值越大,变异程度越小。
用Matlab设计实现图形化界面,设计回调函数,设计完成后,点击GUI图形界面上的菜单或者按钮,在处理操作中能够接收参数,进行必要的交互式操作后,最终能显示运行结果。
1.总结:
数字图像处理这门课程,
图像的基本运算,含有图像的代数运算(算数运算,逻辑运算),领域及模板运算;
图像增强:增强图像信息对比度,改善图片对比度,使目标变得易于识别。处理方法:空间域(灰度变换,直方图均衡化,),频率域。
图像平滑:抑制或消除图像中存在的噪声。处理方法:空域-均值滤波、中值滤波、高斯滤波、双边滤波。频域:理想低通滤波,巴特沃斯低通滤波,高斯低通滤波
图像锐化:检测边缘信息,处理方法:空域:梯度算子、robert算子、sobel算子、prewitt算子。频域:各类高通滤波
图像复原:对于成像过程中的“退化”,指成像系统各种因素的影响,使图像质量降低。一般的图像退化模型可表示为g(x,y)=f(x,y)*h(x,y)+n(x,y),图像复原就是图像退化的逆过程,将退化的过程加以估计,建立退化数学模型,补偿退化过程造成的失真。处理方法:h(x,y)=0,空域滤波去除噪声。n(x,y)=0,逆滤波图像复原;同时考虑退化函数和噪声,维纳滤波图像复原。
图像的形态学处理:用集合来描述目标图像或感兴趣的区域,描述图像各部分的之间的关系,或者描述目标的结构特点。形态学运算通过结构元素对图像集合进行操作,提取有用的信息。处理方法:膨胀:对边界点进行扩充,填充空洞,使边界向外部扩张的过程。 腐蚀:消除物体边界点,使边界向内部收缩的过程,把小于结构元素的物体去除掉。开运算:去除孤立的小点,毛刺,消除小物体,平滑较大物体边界,同时不改变其面积。闭运算:填充物体内细小的空洞,连接临近物体,平滑边界,同时不改变其面积
图像分割:将一幅图像分成具有不同特别性质的区域,将需要的区域进行分离提取,一边进一步提取特征。处理方法:阈值分割,边界分割,区域分割,基于聚类的图像分割,分水岭分割。
2心得:
在完成大作业的过程中,我对数据图像处理这门课程的学习内容又加深了一层理解。在本学期的课程里,我们通过对数字图像的二维处理,利用matlab工具理解了图像处理的一些算法思想,理解算法是如何将数学、逻辑思维映射到现实问题处理上。这门课程不仅仅教会了我们一些数字图像处理的知识,我觉得更重要的是锻炼了我们的编程思维,利用程序语言将具体问题数字化、逻辑化,这也是我在这门课程学习中收获颇丰的一个方面。