飞道的博客

图像处理作业(一)

512人阅读  评论(0)

问题 1 黑白图像灰度扫描

实现一个函数 s = scanLine4e(f, I, loc), 其中 f是一个灰度图像,I 是一个整数,loc 是一个字 符串。当 loc 为’row’时,I 代表行数。当 loc 为’column’时,I 代表列数。输出 s 是对应的相 关行或者列的像素灰度矢量。

调用该函数,提取 cameraman.tif 和 einstein.tif 的中心行和中心列的像素灰度矢量并将扫描 得到的灰度序列绘制成图。

1. 程序

①scanLine4e(f, I, loc)函数


  
  1. function [s] = scanLine4e(f, I, loc)
  2. [row,column]=size(f);
  3. if loc== 'row'
  4. % I 代表行数
  5. s=f(I,:);
  6. elseif loc== 'column'
  7. % I 代表列数
  8. s=f(:,I);
  9. end
  10. end

②主程序


  
  1. img=imread( "资源文件\cameraman.tif");
  2. [centerRow,centerColum]=size(img);
  3. centerRow=round(centerRow/2);
  4. centerColum=round(centerColum/2);
  5. cameramanRow=scanLIne4e(img,centerRow, "row")
  6. cameramanColum=scanLIne4e(img,centerColum, "column")
  7. % 画图
  8. x = linspace(0,256, 256); % 横坐标轴
  9. y1 = cameramanRow;
  10. y2 = cameramanColum;
  11. % 绘图
  12. figure
  13. plotyy(x, y1, x,y2)
  14. scanLIne4e(img,centerRow, "row")

2.运行效果

①cameraman.tif图片

 

图1 cameraman.tif图片行列扫描

②einstein.tif图片

图2 cameraman.tif图片行列扫描

问题 2 彩色图像转换为黑白图像。

图像处理中的一个常见问题是将彩色RGB图像转换成单色灰度图像,第一种常用的方法是 取三个元素R,G,B 的均值。第二种常用的方式,又称为 NTSC 标准,考虑了人类的彩色感知体验,对于 R,G,B 三通道分别采用了不同的加权系数,分别是 R 通道 0.2989,G通道0.5870,B通道0.1140.

实现一个函数g = rgb1gray(f, method).函数功能是将一幅24位的RGB图像,f,转换成灰度图像,g.参数 method 是一个字符串,当其值为’average’ 时,采用 第一种转换方法,当其值为’NTSC’时,采用第二种转换方法。将’NTSC’做为缺省方式。

调用该函数,将提供的图像mandril_color.tif和 lena512color.tiff 用上述两种方法转换成单色 灰度图像,对于两种方法的结果进行简短比较和讨论。

1. 代码

rgb1gray函数


  
  1. function [outputArg] = rgb1gray(f, method)
  2. %函数g = rgb1gray(f, method).函数功能是将一幅24位的RGB图像,f,转换成灰度图像,g.
  3. %参数 method 是一个字符串,当其值为’average’ 时,采用 第一种转换方法,
  4. %当其值为’NTSC’时,采用第二种转换方法。将’NTSC’做为缺省方式。
  5. %获取3通道
  6. red=f(:,:,1);
  7. green=f(:,:,2);
  8. blue=f(:,:,3);
  9. gray=f;
  10. if method== 'average'
  11. %采用 第一种转换方法:取三个元素R,G,B 的均值
  12. gray=(red+green+blue)/3;
  13. elseif method== 'NTSC'
  14. gray=0.2989*red+0.5870*green+0.1140*blue
  15. else
  16. outputArg = "输入参数method错误";
  17. end
  18. outputArg = gray;
  19. end

②主调用函数


  
  1. img=imread( "资源文件\mandril_color.tif");
  2. gray=rgb1gray(img, "average");
  3. imshow(gray)

2.输出结果

①mandril_color.tif

 

图3(左) mandril_color.tif取3通道平均值作为灰度(右)加权NTSC模式

②lena512color.tiff

 

图4(左)lena512color图片取3通道平均值作为灰度(右)加权NTSC模式

3.结论

简单的将3通道的像素值进行平均后得到的灰度图会损失大量细节,图片变得几乎不可见,仅仅保留了少部分密集的深色区域。而用NTSC加权模式后得到的灰度图由于G通道占有最大的权重0.5870,绿色通道能保留较多的细节,因此灰度图在细节保留上几乎不受影响。

问题 3 图像二维卷积函数

实现一个函数 g = twodConv(f, w), 其中 f是一个灰度源图像,w是一个矩形卷积核。要求输出图像g与源图像f大小(也就是像素的行数和列数)一致。请注意,为满足这一要求,对于源图像f需要进行边界像素填补(padding)。这里请实现两种方案。第一种方案是像素复制,对应的选项定义为‘replicate’,填补的像素拷贝与其最近的图像边界像素灰度。第二种方案是补零,对应的选项定义为‘zero’,填补的像素灰度为0,将第二种方案设置为缺省选择。

1.代码


  
  1. ①twodConv函数代码
  2. function [outputArg] = twodConv(f, w,method)
  3. [size_w,t]=size(w)
  4. num=round(size_w/2) -1% 根据卷积核的大小决定要填充多少排
  5. addrow=num*2 %addrow是要添加的圈数,如核大小为3时,添加两圈。核大小为5时,添加4圈
  6. width=size(f, 1)
  7. height=size(f, 2)
  8. if method== 'replicate'
  9. % 增加两圈
  10. top=f(1:width,1); %提取图像的上下左右像素
  11. bottom=f(1:width,height);
  12. left=f(1,1:height);
  13. right=f(width,1:height)
  14. % addrow=2
  15. temp = zeros(addrow*2 +width, addrow*2 + height);
  16. for i=1:addrow
  17. temp(addrow+1:width+addrow,i)=top; %赋值
  18. temp(addrow+1:width+addrow,height+addrow+i)=bottom;
  19. temp(i,addrow+1:height+addrow)=left;
  20. temp(width+addrow+i,addrow+1:height+addrow)=right;
  21. end
  22. temp(addrow+1:width+addrow,addrow+1:height+addrow)=f(1:width,1:height) %中间部分保留为原图
  23. % 图像4个角的赋值
  24. temp(1:addrow,1:addrow)=f(1,1)
  25. temp(width+addrow:width+addrow*2,1:addrow)=f(width,1)
  26. temp(width+addrow:width+addrow*2,height+addrow:height+addrow*2)=f(width,height)
  27. temp(1:addrow,height+addrow:height+addrow*2)=f(1,height)%temp是复制完像素后得到的图片,核为3*3时,会复制两圈
  28. P = zeros(addrow*2 +width,addrow + height);
  29. for i = size_w:(addrow + width) %循环进行卷积操作
  30. for j = size_w:(addrow + height)
  31. for m = 1:size_w
  32. for n = 1:size_w
  33. P(i, j) = P(i, j) + temp(i + m-2, j + n-2)*w(m, n);
  34. end
  35. end
  36. end
  37. end
  38. P = P(size_w:width + addrow, size_w:height);
  39. elseif method== 'zero'
  40. %像素填补0
  41. temp = zeros(addrow, addrow*2 +height ); %创建一张temp图像
  42. temp(size_w:(width +addrow), 1:addrow) = 0;
  43. temp(size_w:(width + addrow),size_w:(height +addrow)) = f;
  44. temp(size_w:(width+ addrow),width + size_w:width+ addrow*2) = 0;
  45. temp(width + size_w:width+ addrow*2, 1:width + addrow*2) = 0;
  46. P = zeros(addrow*2 +width,addrow + height);
  47. for i = size_w:(addrow + width)
  48. for j = size_w:(addrow + height)
  49. for m = 1:size_w
  50. for n = 1:size_w
  51. P(i, j) = P(i, j) + temp(i + m-2, j + n-2)*w(m, n);
  52. end
  53. end
  54. end
  55. end
  56. P = P(size_w:width + addrow, size_w:height);
  57. end
  58. outputArg = P;
  59. end
  60. ②主程序代码
  61. img=imread( "资源文件\cameraman.tif");
  62. w=[0 0 1 0 0;
  63. 0 0 1 0 0;
  64. 1 1 -4 1 1;
  65. 0 0 1 0 0;
  66. 0 0 1 0 0];
  67. % w=[0 1 0;
  68. % 1 -4 1;
  69. % 0 1 0];
  70. convimg=twodConv(img, w, "zero");
  71. % convimg2=convn(img,w);
  72. % convimg2=conv2(img,w);
  73. convimg=uint8(convimg)
  74. imshow(convimg)

2.实验效果

①复制图像边缘像素的卷积

图5 (左)卷积核大小为3时 (右)卷积核大小为5时

②填充0

大小为3*3卷积核卷积效果与matlab自带的conv2函数对比。

图6 (左)卷积核大小为3时填充0的卷积(右)使用conv2

大小为5维卷积核卷积效果与matlab自带的conv2函数对比。

图7 (左)卷积核大小为5时填充0的卷积(右)使用conv2

问题 4 归一化二维高斯滤波核函数

实现一个高斯滤波核函数 w = gaussKernel(sig,m),其中 sig 对应于高斯函数定义中的σ,w 的大小为 m×m。请注意,这里如果m没有提供,需要进行计算确定。如果m已提供但过小, 应给出警告信息提示。w要求归一化,即全部元素加起来和为1

二维高斯滤波核函数如下,其中σxσy 相等。

 

1.代码


  
  1. function [outputArg] = gaussKernel(sig,m)
  2. %高斯滤波核函数 w = gaussKernel(sig,m),
  3. %其中 sig 对应于高斯函数定义中的σ,w 的大小为 m×m。
  4. %请注意,这里如果m没有提供,需要进行计算确定。
  5. %如果m已提供但过小, 应给出警告信息提示。
  6. %w要求归一化,即全部元素加起来和为1
  7. if isempty(m)
  8. %m为空,计算其大小
  9. m=1+2*ceil(3*sig); %若m为空,则定义滤波窗口的大小
  10. elseif m<2
  11. outputArg= 'm(窗口大小)过小,请重新输入参数!'
  12. else
  13. %sig定义高斯函数的标准差
  14. nCenter =floor(m/2); %定义滤波窗口中心的索引
  15. % w 大小为m*m
  16. w=zeros(m,m)
  17. for i=-1*nCenter:nCenter
  18. for j=-1*nCenter:nCenter
  19. w(i+1+nCenter,j+1+nCenter)=exp(-1*((i)^2+(j)^2)/(2*sig^2))/(2*pi*sig^2);
  20. end
  21. end
  22. %归一化
  23. dSum=sum(sum(w));
  24. w=w/dSum;
  25. outputArg = w;
  26. end
  27. end

2. 实验结果

当σ=1时,窗口大小为3*3时,得到的高斯核如下:

问题 5 灰度图像的高斯滤波

调用上面实现的函数,对于问题 1 和 2 中的灰度图像(cameraman, einstein, 以及 lena512color 和mandril_color 对应的NTSC 转换后的灰度图像)进行高斯滤波,采用σ=1,2,3,5。任选一种像素填补方案。

对于σ=1 下的结果,与直接调用相关函数的结果进行比较(可以简单计算差值图像)。然后, 任选两幅图像,比较其他参数条件不变的情况下像素复制和补零下滤波结果在边界上的差别。

1. 代码


  
  1. % 第 5
  2. %问题 12中的灰度图像
  3. img1=imread( "资源文件\cameraman.tif");%einstein.tif
  4. %对应NTSC转化后的灰度图像
  5. img2=imread( "资源文件\mandril_color.tif");%lena512color.tiff
  6. gray=rgb1gray(img2, "NTSC");
  7. sigma= 1 % 2, 3, 5
  8. w=gaussKernel(sigma, 3);
  9. %卷积
  10. result=twodConv(img1, w, "replicate");%复制像素填充
  11. result=uint8(result)
  12. imshow(result)

2.实验效果

①σ=1,2,3,5时cameraman.tif图片滤波效果如图9所示。

 

 

图8 cameraman.tif窗口大小为3,σ分别取1,2,3,5时滤波效果

 

图9 (左)σ取2,窗口大小为5,(右)σ取2,窗口大小为7时滤波效果

窗口大小为3,σ=1,2,3,5时,einstein.tif滤波效果如图10所示。

图10 窗口大小为3,σ分别取1,2,3,5时滤波效果

窗口大小为5,σ=1,2,3,5时,经过NTSC灰度处理后的mandril_color.tif图片滤波效果如图11所示。

 

 

 

图11 窗口大小为5,σ=1,2,3,5时mandril_color.tif灰度图滤波

 

窗口大小为7,σ=1,2,3,5时,经过NTSC灰度处理后的lena512color.tiff图片滤波效果如图12所示。

 

 

图12 窗口大小为5,σ=1,2,3,5时lena512color.tiff灰度图滤波

在窗口大小为7,σ=1的情况下直接调用高斯滤波相关函数,代码如下:


  
  1. %直接调用相关函数
  2. img2=imread( "资源文件\lena512color.tiff");%lena512color.tiff
  3. img2=rgb1gray(img2, "NTSC");
  4. ksize=[7,7]
  5. sigma=1
  6. filter=fspecial( 'gaussian',ksize, sigma); % 构建高斯函数
  7. result2=imfilter(img2, filter, 'replicate');
  8. result2
  9. subimg=result2-result1
  10. subimg=uint8(subimg)
  11. imshow(subimg)

两图对比以及做差得到的图像如图13所示。

(a)手动编写的高斯滤波器效果(b)调用自带函数得到效果

(c)两图做差得到结果

图13 窗口大小为7,σ=1实现的函数与matlab自带函数对比

使用图像cameraman.tif,其他参数条件不变的情况下像素复制和补零下滤波结果在边界上的差别如图14所示,可以看到在填充0的情况下滤波得到的图片会有一圈黑色边框。

图14 (左)复制像素(右)填充0

cameraman图像像素复制和补零下滤波差别

在更换一张青椒图像后发现并没有出现cameraman图像的黑边情况,肉眼很难观察出差别,如图15所示。

图15(左)复制像素(右)填充0

但是两图的边缘像素整体来看,用复制(replicate)方式得到的图像,边缘灰度值更大,填0方式得到的灰度值更小,如图16所示。

图16 (上)复制方式(下)填0方式 青椒图像边缘像素对比

 


转载:https://blog.csdn.net/Toky_min/article/details/108929552
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场