目录
3.1 关于像素值的处理 Value Manipulation
3.1.3 直方图均衡 Histogram Equalisation
3.2 坐标变换 Co-ordinate Manipulation
4.1 High Pass - Edge Detection
基于Matlab的图像处理基础介绍。Matlab提供了丰富的图像处理相关的工具箱,基于Matlab代码实验可以使得图像处理算法的理解变得更加简单直观。
以下所介绍的一些matlab工具函数都限于篇幅只涉及其基本的用法,更丰富的参数设定等可以查阅matlab说明。
一副图像可以看作就是一个像素(pixel)构成的矩形阵列(rectangular array of pixels)。其中,每个像素代表针对对象场景的某个有限区域的某种属性的测量结果。通常所用的属性有两种:
(1) 区域内的平均亮度(brightness),用一个值表示。这样得到的属性值特成为灰度值,由此得到的图像是黑白图像(或者灰度图像,grey image),是单通道图像。
(2) 分别通过红、绿、蓝滤波器滤波后的亮度平均值,包含三个值。这样得到的属性分别记为R,G,B,所得到的图像则是所谓三通道的(RGB)彩色图像。
不管是灰度值,还是R、G、B值,它们都是亮度(brightness)值,通常都用8比特的整数表示,可以表示256种亮度等级。通常255表示白,0表示黑。
但是,亮度值非得是8比特吗。当然不是,这个其实是有历史原因的,参见后文说明。
当我们谈论图像分辨率时,其实包含图像的两个方面的属性。其一是像素的个数;其二则是每个像素表示的比特数(对应于亮度值的等级数)。
以时下流行的4K为例,其大小为4096*2196,考虑彩色图像,有三个通道。因此一张4K分辨率的图像的总的像素个数为:,八百多万个像素,两千多万个亮度值,考虑8比特的亮度值表示,需要2G字节的内存才能表示。
由这一个例子我们可以直观地感受到原始图像的存储是需要巨大的存储空间的。
研究者们发明了很多不同的压缩方法对图像数据进行压缩,包括利用图像中存在大量冗余信息的特征的有效编码方法,以及剔除图像中视觉不敏感的一些不重要的信息(剔除后不会或不太会影响视觉观感)。
具体有哪些图像编码方式超出本文范围,这里就不啰嗦了。。。
Matlab提供了imread(), imshow(),imwrite()用于图像数据的加载、显示和保存。可以自由地处理各种不同的图像格式(通常图像文件的后缀表示图像格式)。
f = imread(‘image file name’);
读入指定的图像文件,其结果作为一个数组赋给变量f。调用size(f)可以知道它的size信息。
imshow(f, [low, high])
f表示要显示的图像,[low, high]表示所显示的强度值范围。如果不指定的话,则用缺省值[0,255]. 低于low的像素点显示为黑色,高于high的像素点显示为白色,相当于做了clipping限幅处理。如果以imshow(f, [])的形式调用而不显式指定low和high的话,会自动地取像素值的最小值赋给low,最大值赋给high。这个自适应地匹配图像像素值范围的显示功能对于图像中像素值范围有限的情况非常有用。
imwrite(array name, ‘file name’)
将数组形式的图像数据保存为指定文件名的图像文件。
所保存的图像格式由文件名中的后缀名推断而得。也可以用另外一个参数进行指定。如果指定的文件名的后缀不是代表一个有效的图像格式的话,则必需用另外一个参数进行指定。
如果指定的文件名的后缀不是代表一个有效的图像格式,又使用了另外一个参数进行指定的话,后者优先度更高。
以上三个函数的基本使用方法参见如下代码示例:
- clear; close all; clc
-
- filename = 'lena1'; % 非matlab内置,需要提供该图片文件
- f = imread([filename '.jfif']);
- fprintf('f size is (%d,%d,%d)\n',size(f));
- figure; imshow(f);
-
- imwrite(f,[filename '.bmp']);
- imwrite(f,[filename '.tiff']);
- imwrite(f,[filename '.jpg']);
-
- % Display a grayscale image
- I = imread('cameraman.tif'); % 'cameraman.tif'是matlab工具箱内置的样本图片
- figure;
- subplot(1,2,1); imshow(I);
-
- % Display a grayscale image, adjust the display range
- subplot(1,2,2); h = imshow(I,[0 80]);
-
- % imwrite(I,'cameraman.img'); % Don't work. Because '.img' is not a valid format postfix
- imwrite(I,'cameraman.img','jpg'); % 指定为jpg格式,但是不如直接用imwrite(I,'cameraman.jpg')
- imwrite(I,'cameraman.tiff','jpg'); % 第三个参数'jpg'指定的格式的优先度更高
- imwrite(I,'cameraman2.tiff'); % 不指定格式,得到的是tiff格式
运行以上代码段可以得到以下结果:
f size is (240,320,3)
Matlab提供了imfinfo()函数用于查询图像文件的基本信息。
比如说在以上代码示例中的最后两条语句,特别是第一条语句生成的文件究竟是什么格式呢?
imwrite(I,'cameraman.tiff','jpg'); % 第三个参数'jpg'指定的格式的优先度更高
imwrite(I,'cameraman2.tiff'); % 不指定格式,得到的是tiff格式
可以用以下两条语句进行查看:
imfinfo('cameraman.tiff')
imfinfo('cameraman2.tiff')
运行结果表明两者确实是不同的格式。
可以用I = rgb2gray(RGB)将真彩色图像 RGB 转换为灰度强度图像 I。rgb2gray 函数通过消除色调和饱和度信息,同时保留亮度,将 RGB图像转换为灰度图。
- lena = imread('lena1.jfif');
- lena_gray = rgb2gray(lena);
- figure;
- subplot(1,2,1);imshow(lena)
- subplot(1,2,2);imshow(lena_gray)
以上的例子说明中都是假定像素值表示的是强度(Intensity)或者说亮度(Brightness),但是其实也并不仅限于此。像素还可以为二进制数,这样的像素构成的图像称为二进制图像(Binary Image),非黑即白。像素还可以表示索引值,基于这个索引值再去查找Look-Up-Table(LUT,查找表)获取其真值。
前面说过,一般的图像中像素值大都是8比特表示,但是非得如此吗?并不是。这个是由多方面原因的(历史原因、路径依赖等等)。8比特适合于计算机存储(计算机存储是按字节单位,1个字节就是8比特,恰好可以存储8比特表示的一个像素的数据);早期很多相机由于技术限制也无法获取高于8比特精度的像素值 ;绝大多数显示装置都是按照每个通道8比特的方式进行设计和实现的,等等等等.
如上所示,8比特并不是必然的。随着技术的发展,有越来越多的器件设备可以生成或者需要更高精度的像素表示。
Matlab提供了方便的对像素值数值格式进行变换的方法。
方法一类似于C语言中的type-cast,其语法如下:
B = data_class_name(A) % data_class_name为matlab所支持的数据类型名,比如说:
B = uint8(A) % 将图像A的数据格式转换为uint8得到图像B
Matlab所支持的数据格式如下表所示:
另一种方法是matlab提供了一组函数用于图像数据格式转换,如下表所示(其用法不言自明,不再另行举例):
图像数据在matlab中是以多维数组的形式表示,其中的个别像素、某个区域内的像素、某个通道的数据等等的访问的基本方法就是多维数组中的部分数据的访问方法。一些基本的数组访问方法如下所示:
A(first:last) % 取1维数组的从first到last的区间(inclusive, 下标从1开始,与python slicing略有不同)
A(first : step : last) % 取1维数组的从first到last的区间,步长为step,相当于下采样。Step可以为负数,相当于倒着取数。
fp = f(end : -1 : 1, :); % 将二维数组的第一维翻转
fc = f(top : bottom, left : right); % 取二维数组的一个矩形区域
fs = f(1 : 2 : end, 1 : 2 : end); % 对二维数组的两个轴方向都进行2倍下采样
作为一个示例,参考以下代码,将灰度图像进行了上下颠倒和左右颠倒处理:
- % fp = f(end : -1 : 1, :); 表示将图像上下颠倒
- % fp = f(:, end : -1 : 1); 表示将图像左右颠倒
- figure;
- subplot(1,2,1); imshow(I(end:-1:1,:));
- subplot(1,2,2); imshow(I(:,end:-1:1));
运行结果如下。
点处理,顾名思义,就是以一个一个像素作为处理单位,针对每个像素的处理互相独立互不影响。主要包括两类处理,一种是关于像素值的处理;另一种是关于坐标的处理。
主要考虑针对表示强度(Intensity, brightness (in a monochrome image) or colour (in a
multichannel image))的像素值的处理。
matlab函数imadjust可以用于灰度图像强度缩放。
J = imadjust(I) % 缺省设定,针对所有像素值中最高1%和最低1%饱和处理
J = imadjust(I,[low_in high_in],[low_out high_out]) % 将像素值从指定输入范围映射到指定输出范围,超出输入范围的像素值做饱和处理
J = imadjust(I,[low_in high_in],[low_out high_out],gamma) % gamma参数用于指定变换方式
gamma参数为1表示线性缩放,大于1表示扩张像素值较大的区间,小于1表示扩张像素值较小的区间。imadjust()的几种调用方式的效果如下所示:
- I = imread('pout.tif'); % Matlab内置样本图像
- J1 = imadjust(I);
- J2 = imadjust(I,[],[],1);
- J3 = imadjust(I,[],[],2);
- J4 = imadjust(I,[],[],0.5);
- figure;
- subplot(2,2,1); imshow(I)
- subplot(2,2,2); imshow(J1)
- subplot(2,2,3); imshow(J3)
- subplot(2,2,4); imshow(J4)
运行结果如下:
显然缺省条件下的调用,以及gamma大于1的调用有助于提高图像的对比度,而gamma小于1的调用则会导致对比度降低。
imadjust也可以用彩色图像的色图(colormap)调整,有点复杂,这里就跳过了。有兴趣者自行查询matlab帮助信息。
matlab函数imhist()可以对输入图像的像素值进行直方图分析。一般直方图分析只针对灰度图像进行。代码示例如下:
- % 直方图
- I = imread('pout.tif'); % Matlab内置样本图像
- h = imhist(I, 100);
- p = imhist(I, 100)*1.0/numel(I);
- figure;
- subplot(2,1,1); plot(h); % 直方图
- subplot(2,1,2); plot(p); % 归一化的直方图,等价于概率密度谱
直方图均衡是将原图像通过某种变换,得到一幅灰度直方图为均匀分布的新图像的方法。其基本思想是对在图像中像素个数多的灰度级进行展宽,而对像素个数少的灰度级进行缩减。据称直方图均衡可以改善图像的观感。
- % 直方图均衡
- I = imread('pout.tif'); % Matlab内置样本图像
- h = histeq(I, 100);
- figure;
- subplot(2,2,1); imshow(I); title('before historgram equalisation');
- subplot(2,2,2); imshow(h); title('after historgram equalisation');
- subplot(2,2,3); plot(imhist(I)); title('before historgram equalisation');
- subplot(2,2,4); plot(imhist(h)); title('after historgram equalisation');
Thresholding也称为图像的二值化处理,就是将图像上的像素点的灰度值基于一个门限分别设置为0或255,也就是将整个图像呈现出明显的只有黑和白的视觉效果。
二值化处理常用于将图像中的物体与其背景分离开来。matlab函数im2bw()用于执行此处理。
BW = im2bw(I,level)
将灰度图像 I
转换为二值图像 BW
,方法是将输入图像中亮度大于 level
的所有像素替换为值 1
(白色),将所有其他像素替换为值 0
(黑色)。此范围与图像的类的可能信号级别相关。因此,0.5
的 level
值对应于类的最小值和最大值之间的中等强度值。
BW = im2bw(X,cmap,level)
使用颜色图 cmap
将索引图像 X
转换为二值图像。
BW = im2bw(RGB,level)
将真彩色图像 RGB
转换为二值图像。
新版本的matlab将采用imbinarize()函数替换掉im2bw(),代码示例如下。彩色图像和黑白图像都可以做二值化处理。
- % 二值化处理
- lena = imread('plane.jpg');
- BW = im2bw(lena,map,0.4);
- figure;
- subplot(2,2,1); imshow(lena,map);
- subplot(2,2,2); imshow(BW);
-
- I = imread('pout.tif');
- Ibw = imbinarize(I,"adaptive");
- subplot(2,2,3); imshow(I);
- subplot(2,2,4); imshow(Ibw);
二值化处理的一个关键参数是门限的选择。虽然手动选择一个门限是一个可能的方案,但是最好还是基于待处理的图像本身来决定门限比较好。
Gonzalez and Woods suggested this method:
1. Choose a threshold arbitrarily.
2. Threshold the image using it.
3. Compute the mean grey value of the pixels with intensities above and below the threshold, and then compute the average of these two values.
4. Use the new value to rethreshold the image.
5. Repeat steps 3 and 4 until the threshold changes by an insignificant amount.
Otsu suggested a method than minimised the between class variance. Matlab函数graythresh(A)实现的是Otsu的方法。
有多种表示颜色的方法,RGB是其中最常用的一种,但是却不是最适合于图像处理的颜色表示方法,因为RGB是一种视觉非均一表示(a perceptually non-uniform representation)。这意味着如果给R/G/B加一个固定的offset,视觉观感上的差异依赖于原始图像中的R/G/B值。有点类似于说缺乏平移不变性。
其它表示颜色的方法有YIQ(ntsc)、YCbCr、HSV等,matlab提供了不同颜色表示方法之间的变换工具:rgb2ntsc, ntsc2rgb, rgb2ycbcr, rgb2lab, rgb2xyz, rgb2hsv
坐标变换的目的是使得原始图像发生变形。比如说,创建全景图像(panoramic images)、对由于镜头畸变导致的图像变形进行补偿等等。
坐标变换通常分为两个阶段进行:
step1: 计算像素的新的坐标
step2: 重采样(resampling)或者内插(interpolation)
有两种变换方式:仿射变换(affine)和非线性变换。
仿射变换通过在变换矩阵中插入适当的值来实现,如下所示:
某个轴可以被缩放、图像整体可以被旋转或者剪切(shear)处理,取决于a~i各参数的取值。Matlab中通过一个tform structure来实现变换,一个 tform structure 通过maketform()函数创建:
tform = maketform(transform_type, transform_parameters);
transform_type 的取值包括: affine, projective, box, composite or custom.
transform_parameters 参数的取值依赖于transform_type. 对于仿射变换,变换参数就是如上所述的矩阵的9个元素。如下例所示:
- T = [2 0 0; 0 3 0; 0 0 1];
- tform = maketform('affine’, T); % Will be replaced by affine2d() or affine3d()
非线性变换通常用于对由成像系统导致发生畸变的图像进行纠正的处理:
在以上坐标变换处理中,所计算出的新的坐标并不总是整数。不能简单地对坐标值做四舍五入的处理(这样会带来额外的distortion,甚至会导致某些输出的像素没有得到赋值。
需要用内插的方式来计算在输出图像中的各个坐标点上的像素值。
matlab提供了tforminv()和imtransform()来进行这种转换计算。与tforminv()相对的是tformfwd(),tformfwd()通常很少使用。
res = tforminv(src, tform, interp);
interp用于选择插值方式,有以下三种选择:
Nearest:uses the nearest neighbour pixel.使用最邻近的像素值
Bilinear (the default):uses a weighted average of the nearest 2 by 2 pixel neighbourhood.双线性,使用最近的2x2邻域的像素值的加权平均
Bicubic:uses a weighted average of the nearest 4 by 4 pixel neighbourhood. 双三次插值,使用4x4邻域内像素值的加权平均。
coming soon...
这里的“图像处理”是狭义的说法,是相对于以上点处理、区域处理而言的以图像整体为对象的处理。
Fourier Transform
coming soon...
参考文献
[1] R.C. Gonzalez, R.E. Woods, S.L. Eddins, (2004) Digital Image Processing Using Matlab
[2] Tim Morris, Image Processing with Matlab, lecture note