CC康纳百川 于 Nov 03, 2020 05:30 pm 编辑
更新于
CC的部落格,CC康纳百川的小窝,与你分享二三事
本文仅作测试使用,因为删掉了原来的webpush 当时id只是7千,现在使用的网站一万多啦,仅仅是因为webpushr域名站点更换问题,做个测试 一、课程设计任务与要求课程设计目的全面学习信号处理类课程所学理论知识,巩固所学知识重点和难点,将理论和实践很好地结合起来; 提高综合运用所学知识独立分析和解决问题的能力; 熟练使用一种高级语言进行编程实现。
课程设计要求使用Matlab(或其它开发工具)编程实现课程设计的内容,课程设计报告打印。 滤波器设计题目尽量避免使用现成的工具箱函数。为便于分析与观察,设计中所有频谱显示中的模拟频率应以实际频率显示,数字频率应对π归一化。 课程设计报告要求: (1)课程设计报告第8周周四下午2:00交,过期不交,无成绩; (2)报告可以打印,按要求标注图表号; (3)互相抄袭,无成绩。
课程设计内容课题名称:彩色图像的边缘检测与处理 课题内容: (1)读入一幅彩色图像(有自己的生活照片); (2)将彩色图像进行三原色分解,分解出R、G、B分量,并用图像显示出来; (3)将彩色图像灰度化,转化为灰度图像并显示; (4)将灰度图像用三种以上典型的边缘检测算子进行边缘检测,显示检测出的边缘。 (5)图像的任意角度旋转、裁剪(1.多种尺寸;2.选择性裁剪出指定目标,如只留下自己肩以上的图像); (6)选做:美颜处理或其他特效处理。
二、设计原理读取、写入和查询图像文件从本质上说,图形文件格式图像并非以 MATLAB 矩阵的形式存储,甚至不必以矩阵的形式存储。大多数图形文件都以包含特定格式信息标签的标头开头,然后是能够以连续流方式读取的位图数据。因此,不能使用标准的 MATLAB I/O 命令 load 和 save 来读取和写入图形文件格式图像。调用专门的 MATLAB 函数从图形文件格式读取和写入图像数据: 要读取图形文件格式图像,请使用 imread 要写入图形文件格式图像,请使用 imwrite 要获取有关图形文件图像的性质信息,请使用 imfinfo
读取图形图像imread 函数能够按照任意受支持的位深读取任意受支持的图形文件中的图像。所读取的大多数图像均为8 位。将这些图像读入内存后,以 uint8 类的形式来存储这些图像。这一规则的主要例外是 MATLAB 支持 16 位数据的 PNG 和 TIFF 图像;如果您读取 16 位的 PNG 或 TIFF 图像,那么该图像以 uint16 类的形式保存。注意对于索引图像,imread 始终将颜色图读入 double 类的数组,即使图像数组本身可能属于 uint8或 uint16 类,也如此。 显示位图图像以下命令可将图像 ngc6543a.jpg 读入工作区变量 RGB,然后用 image 函数来显示该图像: RGB = imread('ngc6543a.jpg');image(RGB)
|
您可以使用 imwrite 函数写入(保存)图像数据。以下语句 load clown imwrite(X,map,'clown.bmp')
|
可用于创建包含 clown 图像的 BMP 文件 彩色图像灰度化rgb2gray是matlab内部一种处理图像的函数,通过消除图像色调和饱和度信息同时保留亮度实现将RGB图像或彩色图转换为灰度图像,即灰度化处理的功能,调用这个功能的格式是I = rgb2gray(RGB),意思是将真彩色图像RGB转换为灰度强度图像I 。 调用格式说明 I = rgb2gray(RGB) 将真彩色RGB图像转换成灰度图像。(RGB并不发生变化) newmap= rgb2gray(map) 返回一个灰度调色板。
|
函数算法 Matlab中默认采用的是对R、G、B分量进行简单加法的公式:0.30R+ 0.59G + 0.11B 但是,这个方法对于Gamma校正的图片(平常所见到的24位真彩色图片均为Gamma校正的图片)并不适用,因为Gamma校正后的分量值不是物理上的功率,不能直接相加,因此,提出一种改进的算法来纠正这一问题。注意这里的2.2次方和2.2次方根,RGB颜色值不能简单直接相加,而是必须用2.2次方换算成物理光功率。因为RGB值与功率并非简单的线性关系,而是幂函数关系,这个函数的指数称为Gamma值,一般为2.2,而这个换算过程,称为Gamma校正。(注意,rgb2ntsc函数也使用相同的权重来计算Y分量) 程序示例 imgrgb = imread('flower.jpg'); figure('Name', '显示真彩色图像') imshow(imgrgb)
imggray = rgb2gray(imgrgb); figure('Name', '显示灰度图像') imshow(imggray)
|
图像边缘检测图像最重要的特征之一就是边缘,它图像分割的主要依据。本次试验学习和了解边缘的基本特征、经典边缘检测算子(包括Prewitt算子,Roberts算子, LoG算子, Canny算子) 1.Prewitt算子是一种一阶微分算子的边缘检测,利用像素点上下、左右邻点的灰度差,在边缘处达到极值检测边缘,去掉部分伪边缘,对噪声具有平滑作用 。其原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成的,这两个方向模板一个检测水平边缘,一个检测垂直边缘。 2.Roberts算子是一种最简单的算子,是一种利用局部差分算子寻找边缘的算子,他采用对角线方向相邻两象素之差近似梯度幅值检测边缘。检测垂直边缘的效果好于斜向边缘,定位精度高。 3.LoG算子一种利用图像强度二阶导数的零交叉点来求边缘点的算法 4.Canny 算法使用 4 个 mask 检测水平、垂直以及对角线方向的边缘。原始图像与每个 mask 所作的卷积都存储起来。对于每个点都标识在这个点上的最大值以及生成的边缘的方向。这样就从可以原始图像生成了图像中每个点亮度梯度图以及亮度梯度的方向。较高的亮度梯度比较有可能是边缘,但是没有一个确切的值来限定多大的亮度梯度是边缘多大又不是,所以 Canny 使用了滞后阈值。 图像旋转 imrotate是matlab中对图像进行旋转的操作命令 调用格式说明 将图像A(图像的数据矩阵)绕图像的中心点旋转angle度, 正数表示逆时针旋转, 负数表示顺时针旋转。返回旋转后的图像矩阵。 B = imrotate(A,angle,method)
|
使用method参数可以改变插值算法,method参数可以为下面这三个值: ‘nearest’:最邻近插值(Nearest-neighbor interpolation) ‘bilinear’: 双线性插值(Bilinear interpolation) ‘bicubic’: 双三次插值(或叫做双立方插值)(Bicubic interpolation) B = imrotate(A,angle,method,bbox) bbox参数用于指定输出图像属性: ‘crop’: 通过对旋转后的图像B进行裁剪, 保持旋转后输出图像B的尺寸和输入图像A的尺寸一样。 ‘loose’: 使输出图像足够大, 以保证源图像旋转后超出图像尺寸范围的像素值没有丢失。 一般这种格式产生的图像的尺寸都要大于源图像的尺寸。 图像裁剪 imcrop是一个函数,在MATLAB中,该函数用于返回图像的一个裁剪区域。可把图像显示在一个图像窗口中, 并允许用户以交互方式使用鼠标选定要剪切的区域。 调用格式: I2 = imcrop(I) X2 = imcrop(X,map) RGB2 = imcrop(RGB)
|
这三种调用格式把图像显示在一个图像窗口中, 并允许用户以交互方式使用鼠标选定要剪切的区域。 I2 = imcrop(I,rect) X2 = imcrop(X,map,rect) RGB2 = imcrop(RGB,rect)
|
这三种格式都指定了要裁剪的矩形区域。 [...] = imcrop(x,y,...) [A,rect] = imcrop(...) [x,y,A,rect] = imcrop(...)
|
美颜效果在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性。 什么是图像滤波? 由于成像系统、传输介质和记录设备等的不完善,数字图像在其形成、传输记录过程中往往会受到多种噪声的污染。另外,在图像处理的某些环节当输入的像对象并不如预想时也会在结果图像中引入噪声。这些噪声在图像上常表现为一引起较强视觉效果的孤立像素点或像素块。一般,噪声信号与要研究的对象不相关它以无用的信息形式出现,扰乱图像的可观测信息。对于数字图像信号,噪声表为或大或小的极值,这些极值通过加减作用于图像像素的真实灰度值上,对图像造成亮、暗点干扰,极大降低了图像质量,影响图像复原、分割、特征提取、图像识别等后继工作的进行。要构造一种有效抑制噪声的滤波器必须考虑两个基本问题:能有效地去除目标和背景中的噪声;同时,能很好地保护图像目标的形状、大小及特定的几何和拓扑结构特征。 非线性滤波器:一般说来,当信号频谱与噪声频谱混叠时或者当信号中含有非叠加性噪声时如由系统非线性引起的噪声或存在非高斯噪声等),传统的线性滤波技术,如傅立变换,在滤除噪声的同时,总会以某种方式模糊图像细节(如边缘等)进而导致像线性特征的定位精度及特征的可抽取性降低。而非线性滤波器是基于对输入信号的一种非线性映射关系,常可以把某一特定的噪声近似地映射为零而保留信号的要特征,因而其在一定程度上能克服线性滤波器的不足之处。 双边滤波(Bilateral filter)是一种非线性滤波方法(空间权值+相似权值)——空间权值:模糊去噪;相似权值:保护边缘。 双边滤波原理双边滤波具有两个权重:空间权重与相似权重 1)空间权重:与像素位置有关,为像素之间的距离(欧式距离,空间度量),故可定义为全局变量放在循环外 2)相似权重:与像素值大小有关,为像素值之间的距离(辐射距离,相似性度量),根据像素值不同而不同,需要放在循环内 3)两者结合,得到基于空间距离 双边滤波实现:实际应用时,根据需要对积分采用离散形式表示,滤波半径根据需要自行设置,在进行滤波前,需将数据转换为浮点型等。 双边滤波器(Bilateral filter)为使图像平滑化的非线性滤波器,它除了使用像素之间几何上的靠近程度之外,还多考虑了像素之间的灰度差异, 使得双边滤波器能够有效的将图像上的噪声去除,同时保存图像上的边缘信息。双边滤波器的好处是可以做边缘保护(edge preserving),一般用高斯滤波、均值滤波等滤波器去降噪,会较明显地模糊边缘,对于高频细节的保护效果并不明显。双边滤波器顾名思义比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波。 空间距离:指的是邻域内某点与中心点的欧式距离。空间域高斯函数其数学形式为(这就是高斯滤波核): 其中(xi,yi)为邻域内某点位置,(xc,yc)为中心点的位置,sigma为空间域标准差。 灰度距离:指的是邻域内某点灰度与中心点灰度的差的绝对值。值域高斯函数其数学形式为: 其中gray(xi,yi)为邻域内某点灰度值,gray(xc,yc)为中心点灰度值,sigma为值域标准差。 对于高斯滤波,仅用空间距离的权值系数核与图像卷积后,确定中心点的灰度值。即认为离中心点越近的点,其权重系数越大。双边滤波中加入了对灰度信息的权重,即在邻域内,灰度值越接近中心点灰度值的点的权重更大,灰度值相差大的点权重越小。所以掩膜最终权重大小,则由空间域高斯核函数和值域高斯核函数共同确定。 σ的意义及选取 1.空间域sigma-d选取: sigma-d越大,图像越平滑,趋于无穷大时,每个权重都一样,类似均值滤波; sigma-d越小,中心点权重越大,周围点权重越小,对图像的滤波作用越小,趋于零时,输出等同于原图。 2.值域sigma-r选取: Sigma-r越大,边缘越模糊,极限情况为simga无穷大,值域系数近似相等(忽略常数时,将近为exp(0)= 1),与高斯模板(空间域模板)相乘后可认为等效于高斯滤波。 Sigma-r越小,边缘越清晰,极限情况为simga无限接近0,值域系数除了中心位置,其他近似为0(接近exp(-∞)=0),与高斯模板(空间域模板)相乘进行滤波的结果等效于原图像 三、程序设计- 图像读取使用以下代码即可完成
[FileName, FilePath]=uigetfile('*.jpg;*.png;*.tif;*.img;*.gif;','请选择图像数据'); str=[FilePath FileName];i=imread(str);
|
这里借用数组存放着图片文件名和路径,同时限定了图片格式,用户也可手动选择其他格式 char - 字符数组,字符数组是一个字符序列,就像数值数组是一个数字序列一样。它的典型用途是将一小段文本作为一行字符存储在字符向量中。 但为了方便避免每次选择,测试过程中采取直接读取方式i=imread(‘ME.jpg’); - 使用通道提取RGB分量,事实上你看到的并不是只有单一的某种颜色,但是三者的确有者明显的差别
RGB通道分量的提取后,再把分量串联起来作为一个对比结果也是正确的 cat - 串联数组。此 MATLAB 函数 沿维度 dim 将 B 串联到 A 的末尾。 我们需要合成的是三维(彩色)图像,所以以下可以实现 close all;clear;clc; i= imread ('ME.jpg'); ir=i(:,:,1);ig=i(:,:,2);ib=i(:,:,3); figure('numbertitle','off','name','图像三原色分解与合成'); subplot(1,2,1);imshow(i);title('原图'); X=cat(3,ir,ig,ib);subplot(122),imshow(X);title('合成真彩色图像');
|
当然合并方式不止上面那一种,比如 A(:,:,1)=r;A(:,:,2)=g;A(:,:,3)=b;image(A)
|
也是可以完成三通道合并。 至此,课程要求的内容已完成,但上面这种RGB通道分量的提取的效果,并不是我想要的结果。因此,我们使用图像的阈值分割。阈值分割的基本思想是确定一个阈值,然后把每个像素点的灰度值和阈 值相比较,根据比较的结果把该像素划分为两类——前景或背景。图像阈值化分割是一种传统的最常用的图像分割方法,因其实现简单、计算量小、性能较稳定而成为图像分割中最基本和应用最广泛的分割技术。它特别适用于目标和背景占据不同灰度级范围的图像。它不仅可以极大的压缩数据量,而且也大大简化了分析和处理步骤,因此在很多情况下,是进行图像分析、特征提取与模式识别之前的必要的图像预处理过程。图像阈值化的目的是要按照灰度级,对像素集合进行一个划分,得到的每个子集形成一个与现实景物相对应的区域,各个区域内部具有一致的属性,而相邻区域布局有这种一致属性。这样的划分可以通过从灰度级出发选取一个或多个阈值来实现。基本原理是:通过设定不同的特征阈值,把图像象素点分为若干类。常用的特征包括:直接来自原始图像的灰度或彩色特征;由原始灰度或彩色值变换得到的特征。 设置红、绿、蓝三种颜色提取阈值(越大越严格),具体效果不再占用篇幅演示 转化为灰度图像则直接调用rgb2gray函数即可 边缘检测,调用edge函数设定相应的参数即可,结果如下图 图像旋转,调用imrotate函数设定相应的参数即可,结果如下图 图像裁剪主要使用到的是imcrop函数,通过是否矩形裁剪区域大小来供用户手动裁剪或
自动裁剪,同时自动裁剪加上了红色裁剪区域边框以供用户对比查看,当然这得力于Matlab强大的交互查看功能 然后其实它能通过蒙版遮罩的方式达到抠图的效果,不过很简单,边缘细节处理的都不是很好,背景的话要不就是全黑要么你选择白色,下图是一个示例, - 图像美颜,即用到了上面提到的双边滤波器,经测试后得到比较好的美颜效果图像如下
这张原照片仔细观察的话,其实脸上有各种痘痘,或者手抓后留下的痕迹,处理后胡子以及下巴上的痣也几乎看不出来了,皮肤更加光滑细腻,嘴唇颜色也红润了些许,但要想做到更好的话,我想大概需要优化皮肤美白效果,分别改变三个参数大小发现要不就是美颜效果不是很明显,要么就是过于朦胧,或过于虚化,像动漫里的人物,调试了许久后选择了当前参数,也符合之前查阅资料的的理论分析结果,以上生成结果图片都会自动保存在工作目录方便引用,这里不做复制粘贴 四、总结遇到的问题和解决方法关于从文件管理器读取文件,之前使用的时候记得,但太久没用了,不过有保存当时的代码,所以直接拿过来用了 图像手动裁剪操作,因为需要高速用户如何裁剪与得到裁剪结果,所以需要做一个tips,但是使用title并没有成功显示,它有时候的确不是很好用,试过了str、note输出在命令行或者图片顶端,但因为字数过多不是很好看,最后选择msgbox,并把窗口置顶,调整窗口位置和字体大小,未完成操作不允许执行下一步 美颜效果虽然方案多,但要想比较简单效果比较好的话还是很难的,毕竟Matlab不是PS,或者说做个GUI界面出来,实现参数可调,但好的效果基本就在那一段,没什么可调的,所以用户选择图片后,就可以得到所有结果了
设计心得与体会这次的课程设计时间虽然短暂,但我感觉收获颇多。之前接触MATLAB时对其在信号处理方面的兴趣就很感兴趣,自己利用课余时间也略有小研究,因此在图像处理的任务上,能够较轻松的完成。但由于自己对数字信号处理的理论知识理解不深,对数字滤波器的设计缺少知识,对于任务一研究了较长时间,设计过程中通过回顾滤波器设计的相关内容,再通过利用参考文献与网络,成功完成了任务。这次课程设计,让我加深了对之前抽象概念的理解,巩固了之前所了解的理论知识,并能很好的理解和掌握数字信号处理中的基本概念、基本原理、基本分析方法。同时掌握编程方法的技巧,与高级语言的程序设计相比,MATLAB环境下可以更方便、快捷地进行设计,节省大量时间,且参数的修改也十分方便,还可以进一步进行优化设计。 这次的课程设计让我再次感受到MATLAB的强大功能,在今后的日子里,自己还需要不断的摸索。 五、参考文献MATLAB 的 PDF 文档(来自Mathworks中文官网) • MATLAB 图形 (R2020a) • MATLAB 函数参考 (R2020a) CSDN博客 六、程序源代码清单close all;clear;clc;
[FileName, FilePath]=uigetfile('*.jpg;*.png;*.tif;*.img;*.gif;','请选择图像数据');str=[FilePath FileName];i=imread(str); figure('numbertitle','off','name','原始图像') imshow(i);title('原始图像');imwrite(i,'原始图像.jpg','jpg');
ir=i(:,:,1);ig=i(:,:,2);ib=i(:,:,3); figure('numbertitle','off','name','图像三原色分解') subplot(2,2,1);imshow(i);title('原图'); subplot(2,2,2);imshow(ir);title('red 红色分量');imwrite(ir,'红色分量.jpg','jpg'); subplot(2,2,3);imshow(ig);title('green 绿色分量');imwrite(ig,'绿色分量.jpg','jpg'); subplot(2,2,4);imshow(ib);title('blue 蓝色分量');imwrite(ib,'蓝色分量.jpg','jpg');
g=rgb2gray(i); figure('numbertitle','off','name','原始图像与其对应的灰度图像'); subplot(1,2,1),imshow(i);title(' 图一 原始图像'); subplot(1,2,2),imshow(g);title(' 图二 灰度图像');imwrite(g,'灰度图像.jpg','jpg');
g=im2double(g); figure('numbertitle','off','name','边缘检测图像'); subplot(1,5,1),imshow(g),title('原图的灰度图'); PF=edge(g,'prewitt'); subplot(1,5,2),imshow(PF),title('Prewitt算子');imwrite(PF,'Prewitt算子边缘检测.jpg','jpg'); RF=edge(g,'roberts'); subplot(1,5,3),imshow(RF),title('Roberts算子');imwrite(RF,'Roberts算子边缘检测.jpg','jpg'); LF=edge(g,'log'); subplot(1,5,4),imshow(LF),title('Log算子');imwrite(LF,'Log算子边缘检测.jpg','jpg'); CF=edge(g,'canny'); subplot(1,5,5),imshow(CF),title('Canny算子');imwrite(CF,'Canny算子边缘检测.jpg','jpg');
a1=imrotate(i,-30,'nearest','loose'); a2=imrotate(i,-45,'nearest','loose'); a3=imrotate(i,-60,'nearest','loose'); a4=imrotate(i,-90,'nearest','loose'); a5=imrotate(i,-135,'nearest','loose'); a6=imrotate(i,45,'nearest','loose'); a7=imrotate(i,135,'nearest','loose'); a8=imrotate(i,180,'nearest','loose'); figure('numbertitle','off','name','旋转任意角度的图像'); subplot(3,3,5),imshow(i),title('未经旋转'); subplot(3,3,1),imshow(a1),title('顺时针旋转30°');imwrite(a1,'顺时针旋转30°.jpg','jpg'); subplot(3,3,2),imshow(a2),title('顺时针旋转45°');imwrite(a2,'顺时针旋转45°.jpg','jpg'); subplot(3,3,3),imshow(a3),title('顺时针旋转60°');imwrite(a3,'顺时针旋转60°.jpg','jpg'); subplot(3,3,4),imshow(a4),title('顺时针旋转90°');imwrite(a4,'顺时针旋转90°.jpg','jpg'); subplot(3,3,6),imshow(a5),title('顺时针旋转135°');imwrite(a5,'顺时针旋转135°.jpg','jpg'); subplot(3,3,7),imshow(a6),title('逆时针旋转45°');imwrite(a6,'逆时针旋转45°.jpg','jpg'); subplot(3,3,8),imshow(a7),title('逆时针旋转135°');imwrite(a7,'逆时针旋转135°.jpg','jpg'); subplot(3,3,9),imshow(a8),title('逆时针旋转180°');imwrite(a8,'逆时针旋转180°.jpg','jpg');
rect=[75 68 130 112]; I1=imcrop(i,rect); set(0,'defaultFigurePosition',[100,100,1000,500]); set(0,'defaultFigureColor',[1 1 1]) figure('numbertitle','off','name','裁剪图像'); subplot(2,2,1),imshow(i),title('原始图像'); rectangle('Position',rect,'LineWidth',2,'EdgeColor','r') subplot(2,2,2),imshow(I1),title('自动剪切图像');imwrite(I1,'自动剪切图像.jpg','jpg');
subplot(2,2,3),imshow(i); f = msgbox({'按住鼠标以选择初始裁剪区域','双击以确认','稍等一会儿即可查看裁剪结果'},'操作提示'); af = get( f, 'CurrentAxes' ); cf = get( af, 'Children' ); set( cf, 'FontSize', 12); set(f,'WindowStyle','modal','Position',[300 300 200 100]);
[x,y,I2,rect]=imcrop(i); subplot(2,2,4),imshow(I2),title('手动裁剪结果');imwrite(I2,'手动剪切图像.jpg','jpg');
tempsize = 5; sigma1 = 5; sigma2 = 0.08; img = double(padarray(i,[tempsize,tempsize],0))/255;
imgr = img(:,:,1);imgg = img(:,:,2);imgb = img(:,:,3);[m,n] = size(imgr); figure('numbertitle','off','name','双边滤波处理后的图像'); subplot(1,2,1),imshow(i),title('原图');
img(:,:,1) = B_filter(imgr,tempsize,sigma1,sigma2); img(:,:,2) = B_filter(imgg,tempsize,sigma1,sigma2); img(:,:,3) = B_filter(imgb,tempsize,sigma1,sigma2); subplot(1,2,2),imshow(img(tempsize+1:m-tempsize,tempsize+1:n-tempsize,:)) title('双边滤波处理后图像') imwrite(img(tempsize+1:m-tempsize,tempsize+1:n-tempsize,:),'美颜图像.jpg','jpg');
function out = B_filter(Img,tempsize,sigma0,sigma1) gauss = fspecial('gauss',2*tempsize+1,sigma0); [m,n] = size(Img); for i = 1+ tempsize : m - tempsize for j = 1+ tempsize : n - tempsize temp = abs(Img(i - tempsize:i + tempsize,j - tempsize:j + tempsize) - Img(i,j)); temp = exp(-temp.^2/(2*sigma1^2)); filter = gauss.*temp; filter = filter/sum(filter(:)); Img(i,j) = sum(sum((Img(i - tempsize:i + tempsize,j - tempsize:j + tempsize).*filter))); end end out = Img; end
|
本文阅读完毕,你可以选择
在浏览器中阅读 » | 直达评论区 »
|