灰度可以认为是亮度,灰色图片中黑白的深浅程度,范围一般为0~255。图像数字化为二维矩阵后,每个点的值都代表一个像素点的灰度值。
灰度值的表示范围,灰度级时,称图片为k比特图片。当然灰度级越高,图片的细节则越清晰,因为有更多的灰度值来描述图片。但是灰度级越大,图片所需要的存储空间也会越大,因此一般会采用256灰度级。
空间域处理图像(直接对f(x,y)进行操作)T[ ]就像是一个操作的函数,将图像f (x,y)输入后会进行不同的操作,操作结果为g (x,y)。
一般用上述形式表示变换的过程,r和S分别表示变换前后的像素值(灰度),T表示某种变换函数
目前学到的有灰度变换和空间滤波,灰度变换包括图像反转,对数变换,幂次变换,直方图均衡、匹配,空间滤波包括平滑滤波和锐化滤波
这里主要是线性变换,将某一范围的灰度值映射到另一个线性范围
我们对某位患者的胸片进行处理,原图中有白色絮状物体,但是图片整体偏暗,不便于观察,于是我们进行线性的反转,将较亮部位与较暗部位进行互换,如下图所示,肉眼可见观察的更加清晰了。
图像反转代码
imadjust(f,[low_in, high_in ],[low_out, high_out])将图片的[low_in, high_in]范围映射到[low_out, high_out],我们需要进行反转,就将low_out > low_in
f=imread('C:\Matlab Project\image\Fig0303(a)(breast).tif');
g=imadjust(f,[0 0.8],[1 0]);
figure(1)
title('图像反转');
subplot(1,2,1);imshow(f)
subplot(1,2,2);imshow(g)
根据对数函数的特征,会将输入图像的灰度值中较暗部分 r < L/4 部分映射到 [0 3L/4]这个较大的范围,而较亮部分则会映射到较小的区域。这个函数会将图像暗处的细节放大,压缩亮处的细节。最具代表的就是对傅里叶频谱的对数运算,从对比图中可以看到暗处的细节被放大输出
代码
f=imread('C:\Matlab Project\image\Fig0305(a)(spectrum).tif');
g=0.8*log(1+double(f));
figure()
subplot(1,2,1);imshow(f)
subplot(1,2,2);imshow(g)
当<1时,效果和对数函数相似,放大暗处细节,压缩亮处细节,随着数值减少,效果越强
当>1时,放大亮处细节,压缩暗处细节,随着数值增大,效果越强
代码
测试为>1的情况,图片效果和对数变换差别不大
测试=0.1的情况,将暗处细节放大,亮处细节压缩
f=imread('C:\Matlab Project\image\Fig0305(a)(spectrum).tif');
g=double(f).^0.1;
figure()
subplot(1,2,1);imshow(f,[])
subplot(1,2,2);imshow(g,[])
测试=10的情况,将暗处细节放大,压缩亮出细节,图片变得更暗了
f=imread('C:\Matlab Project\image\Fig0305(a)(spectrum).tif');
g=double(f).^10;
figure()
subplot(1,2,1);imshow(f,[])
subplot(1,2,2);imshow(g,[])
由于灰度级,是有2的次方构成,每个像素值看作是由K个二进制数组成的
于是每个平面k-1,k-2,....,1,0 中的每一个像素值都等于该像素在该平面的项数值
代码
感觉有些冗余,但是目前还不知道怎么修改,以后再改
f=imread('C:\Matlab Project\image\original_test_pattern.tif');
g=double(f);
L1=mod(g,2);
L2=mat2gray(mod(g./2,2));
L3=mat2gray(mod(g./(2.^2),2));
L4=mat2gray(mod(g./(2.^3),2));
L5=mat2gray(mod(g./(2.^4),2));
L6=mat2gray(mod(g./(2.^5),2));
L7=mat2gray(mod(g./(2.^6),2));
L8=mat2gray(mod(g./(2.^7),2));
figure()
subplot(3,3,1);imshow(L1),title('第一层');
subplot(3,3,2);imshow(L2),title('第二层');
subplot(3,3,3);imshow(L3),title('第三层');
subplot(3,3,4);imshow(L4),title('第四层');
subplot(3,3,5);imshow(L5),title('第五层');
subplot(3,3,6);imshow(L6),title('第六层');
subplot(3,3,7);imshow(L7),title('第七层');
subplot(3,3,8);imshow(L8),title('第八层');
subplot(3,3,9);imshow(f),title('原图');
表示像素值在图像中出现的次数,下图显示的是图片对应的直方图
代码
f=imread('C:\Matlab Project\image\Fig0308(a)(pollen).tif');
h1=imhist(f,256); %函数imhist 得到一维数组频数 不直接输出
h2=h1(1:10:256); %转化为条形图
horz=1:10:256;
figure()
subplot(1,2,1);imshow(f);
subplot(1,2,2); h2=bar(horz,h2,0.6);
axis([0 255 0 15000]) %直方图输出范围(横0-256 纵 0-15000 )
set(gca,'xtick',0:50:255)
set(gca,'ytick',0:2000:12000)
归一化直方图: 表示像素值在图像中出现的概率
可以将函数变换到直方图较均衡分布的状态
直方图变换的函数,通过归一化直方图相加获得
代码
matlab 中使用histeq(f,256)直接获得均衡后的图像
f=imread('C:\Matlab Project\image\Fig0308(a)(pollen).tif');
h1=imhist(f,256);
h2=histeq(f,256); %histeq均衡后得到为图像
figure(1)
subplot(2,2,1);imshow(f);
subplot(2,2,2);plot(h1);
subplot(2,2,3);imshow(h2);
subplot(2,2,4);imhist(h2);
hnorm=imhist(f)./numel(f); %注意为原图像的概率,不是均衡后的
cdf=cumsum(hnorm); % 变换函数S=T(r)
x=linspace(0,1,256);
figure(2)
plot(x,cdf);
axis([0 1 0 1])
set(gca,'xtick',0:0.2:1)
set(gca,'ytick',0:0.2:1)
直方图匹配是在均衡的基础上进行,希望最后处理后的图像符合某种特定的直方图分布。为什么要这样呢,主要是因为均衡是将整个图像整体的均衡,可能将整体的图片变化的太暗或是太亮,如图,左边为原图,中间为直方图均衡,右边为直方图匹配。
通过下图直方图均衡的变化函数,也能看出,均衡将函数值变得偏大,图像便整体偏大
再分析图像变化前后的直方图分布,我们可以发现,原图的像素值主要分布在较暗和较亮两个极端位置,但是直方图均衡就粗暴的将大家都平均了。
假设我们希望最后图像归一化直方图为
求相应的变换函数
而输入图像的变换函数为
我们希望他们相等
便可求出S到Z的映射
代码
matlab 通过 histeq(f,hspec) 函数来实现,hspec为最后希望的直方图
由于输入图像的直方图类似双峰高斯函数,所以我们将hspec设置为双峰高斯函数由函数twomodegauss获得
twomodegauss
function p = twomodegauss(m1,sig1,m2,sig2,A1,A2,k)
%TWOMODEGAUSS 返回双峰高斯函数
% p = twomodegauss(m1,sig1,m2,sig2,A1,A2,k)
% p为标准化256个元素,sum(p)=1,
% (m1,sig1),(m2,sig2)分别为双峰的均值和标准差,
% A1,A2分别为峰值,k为基数
c1 = A1 * (1 / ((2 * pi) ^ 0.5) * sig1);
k1 = 2 * (sig1 ^ 2);
c2 = A2 * (1 / ((2 * pi) ^ 0.5) * sig2);
k2 = 2 * (sig2 ^ 2);
z = linspace(0, 1, 256);
p = k+c1*exp(-((z-m1).^2)./k1)+c2*exp(-((z-m2).^2)./k2);
p = p./sum(p(:));
实现代码
f=imread('C:\Matlab Project\image\Fig0310(a)(Moon Phobos).tif');
p = twomodegauss(0.15,0.05, 0.75, 0.05,1, 0.07, 0.002);
g=histeq(f,p);
figure(1)
subplot(1,3,1);imshow(f);
subplot(1,3,2);imshow(histeq(f,256));
subplot(1,3,3);imshow(g);