问题 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)函数
function [s] = scanLine4e(f, I, loc)
[row,column]=size(f);
if loc=='row'
% I 代表行数
s=f(I,:);
elseif loc=='column'
% I 代表列数
s=f(:,I);
end
end
②主程序
img=imread("资源文件\cameraman.tif");
[centerRow,centerColum]=size(img);
centerRow=round(centerRow/2);
centerColum=round(centerColum/2);
cameramanRow=scanLIne4e(img,centerRow,"row")
cameramanColum=scanLIne4e(img,centerColum,"column")
% 画图
x = linspace(0,256, 256); % 横坐标轴
y1 = cameramanRow;
y2 = cameramanColum;
% 绘图
figure
plotyy(x, y1, x,y2)
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函数
function [outputArg] = rgb1gray(f, method)
%函数g = rgb1gray(f, method).函数功能是将一幅24位的RGB图像,f,转换成灰度图像,g.
%参数 method 是一个字符串,当其值为’average’ 时,采用 第一种转换方法,
%当其值为’NTSC’时,采用第二种转换方法。将’NTSC’做为缺省方式。
%获取3通道
red=f(:,:,1);
green=f(:,:,2);
blue=f(:,:,3);
gray=f;
if method=='average'
%采用 第一种转换方法:取三个元素R,G,B 的均值
gray=(red+green+blue)/3;
elseif method=='NTSC'
gray=0.2989*red+0.5870*green+0.1140*blue
else
outputArg = "输入参数method错误";
end
outputArg = gray;
end
②主调用函数
img=imread("资源文件\mandril_color.tif");
gray=rgb1gray(img,"average");
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.代码
①twodConv函数代码
function [outputArg] = twodConv(f, w,method)
[size_w,t]=size(w)
num=round(size_w/2) -1% 根据卷积核的大小决定要填充多少排
addrow=num*2 %addrow是要添加的圈数,如核大小为3时,添加两圈。核大小为5时,添加4圈
width=size(f, 1)
height=size(f, 2)
if method=='replicate'
% 增加两圈
top=f(1:width,1); %提取图像的上下左右像素
bottom=f(1:width,height);
left=f(1,1:height);
right=f(width,1:height)
% addrow=2
temp = zeros(addrow*2 +width, addrow*2 + height);
for i=1:addrow
temp(addrow+1:width+addrow,i)=top; %赋值
temp(addrow+1:width+addrow,height+addrow+i)=bottom;
temp(i,addrow+1:height+addrow)=left;
temp(width+addrow+i,addrow+1:height+addrow)=right;
end
temp(addrow+1:width+addrow,addrow+1:height+addrow)=f(1:width,1:height) %中间部分保留为原图
% 图像4个角的赋值
temp(1:addrow,1:addrow)=f(1,1)
temp(width+addrow:width+addrow*2,1:addrow)=f(width,1)
temp(width+addrow:width+addrow*2,height+addrow:height+addrow*2)=f(width,height)
temp(1:addrow,height+addrow:height+addrow*2)=f(1,height)%temp是复制完像素后得到的图片,核为3*3时,会复制两圈
P = zeros(addrow*2 +width,addrow + height);
for i = size_w:(addrow + width) %循环进行卷积操作
for j = size_w:(addrow + height)
for m = 1:size_w
for n = 1:size_w
P(i, j) = P(i, j) + temp(i + m-2, j + n-2)*w(m, n);
end
end
end
end
P = P(size_w:width + addrow, size_w:height);
elseif method=='zero'
%像素填补0
temp = zeros(addrow, addrow*2 +height ); %创建一张temp图像
temp(size_w:(width +addrow), 1:addrow) = 0;
temp(size_w:(width + addrow),size_w:(height +addrow)) = f;
temp(size_w:(width+ addrow),width + size_w:width+ addrow*2) = 0;
temp(width + size_w:width+ addrow*2, 1:width + addrow*2) = 0;
P = zeros(addrow*2 +width,addrow + height);
for i = size_w:(addrow + width)
for j = size_w:(addrow + height)
for m = 1:size_w
for n = 1:size_w
P(i, j) = P(i, j) + temp(i + m-2, j + n-2)*w(m, n);
end
end
end
end
P = P(size_w:width + addrow, size_w:height);
end
outputArg = P;
end
②主程序代码
img=imread("资源文件\cameraman.tif");
w=[0 0 1 0 0;
0 0 1 0 0;
1 1 -4 1 1;
0 0 1 0 0;
0 0 1 0 0];
% w=[0 1 0;
% 1 -4 1;
% 0 1 0];
convimg=twodConv(img, w,"zero");
% convimg2=convn(img,w);
% convimg2=conv2(img,w);
convimg=uint8(convimg)
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.代码
function [outputArg] = gaussKernel(sig,m)
%高斯滤波核函数 w = gaussKernel(sig,m),
%其中 sig 对应于高斯函数定义中的σ,w 的大小为 m×m。
%请注意,这里如果m没有提供,需要进行计算确定。
%如果m已提供但过小, 应给出警告信息提示。
%w要求归一化,即全部元素加起来和为1
if isempty(m)
%m为空,计算其大小
m=1+2*ceil(3*sig); %若m为空,则定义滤波窗口的大小
elseif m<2
outputArg='m(窗口大小)过小,请重新输入参数!'
else
%sig定义高斯函数的标准差
nCenter =floor(m/2); %定义滤波窗口中心的索引
% w 大小为m*m
w=zeros(m,m)
for i=-1*nCenter:nCenter
for j=-1*nCenter:nCenter
w(i+1+nCenter,j+1+nCenter)=exp(-1*((i)^2+(j)^2)/(2*sig^2))/(2*pi*sig^2);
end
end
%归一化
dSum=sum(sum(w));
w=w/dSum;
outputArg = w;
end
end
2. 实验结果
当σ=1时,窗口大小为3*3时,得到的高斯核如下:
问题 5 灰度图像的高斯滤波
调用上面实现的函数,对于问题 1 和 2 中的灰度图像(cameraman, einstein, 以及 lena512color 和mandril_color 对应的NTSC 转换后的灰度图像)进行高斯滤波,采用σ=1,2,3,5。任选一种像素填补方案。
对于σ=1 下的结果,与直接调用相关函数的结果进行比较(可以简单计算差值图像)。然后, 任选两幅图像,比较其他参数条件不变的情况下像素复制和补零下滤波结果在边界上的差别。
1. 代码
% 第5题
%问题1和2中的灰度图像
img1=imread("资源文件\cameraman.tif");%einstein.tif
%对应NTSC转化后的灰度图像
img2=imread("资源文件\mandril_color.tif");%lena512color.tiff
gray=rgb1gray(img2,"NTSC");
sigma=1 %2,3,5
w=gaussKernel(sigma,3);
%卷积
result=twodConv(img1, w,"replicate");%复制像素填充
result=uint8(result)
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的情况下直接调用高斯滤波相关函数,代码如下:
%直接调用相关函数
img2=imread("资源文件\lena512color.tiff");%lena512color.tiff
img2=rgb1gray(img2,"NTSC");
ksize=[7,7]
sigma=1
filter=fspecial('gaussian',ksize, sigma); % 构建高斯函数
result2=imfilter(img2, filter, 'replicate');
result2
subimg=result2-result1
subimg=uint8(subimg)
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方式 青椒图像边缘像素对比