第一章 绪言
数字图像处理
MATLAB
MATLAB是matrix&laboratory两个词的组合,意为矩阵工厂(矩阵实验室)。是由美国mathworks公司发布的主要面对科学计算、可视化以及交互式程序设计的强大数学软件。——详情
数字图像表示
坐标约定
- 像素坐标:图像处理工具箱使用(r, c)而不是(x, y)来表示行与列,并且该坐标系的原点在(r, c) = (1, 1)处。
- 空间坐标:这一坐标约定以x表示列,y表示行。
作为矩阵的图像
- 一幅数字图像可表示成一个MATLAB矩阵。一般使用M和N分别表示矩阵中的行与列。一个1×N的矩阵被称为一个行向量, 而一个M×1的矩阵被称为一个列向量。一个1×1的矩阵则被称为标量。
图像的输入/输出及显示(函数)
- imread(‘filename’):用来读取图片
filename是一个包含图像文件全名(也可以有文件路径)的字符串
>> f = imread('butterfly.jpg');
>> g = imread('D:\picture\素材\cat.jpg');
- imshow(f):用来显示图像
f 是一个图像数组
>> f = imread('D:\picture\素材\cat.jpg');
>> imshow(f)
注意:如果之后用imshow()又显示了一幅图像g,MATLAB会用新图像取代图形窗口中的图像。若想要保留第一幅图像并输出第二幅图像,可以调用figure函数创建新窗口:
>> figure;
>> imshow(g)
imwrite(f, ‘filename’):用于将图像写入当前目录下
f 是要写入的图像数组,filename是存到目录后的文件名size(f) 函数可以给出一幅灰度图像的行数和列数(如果图片是彩色的,可以用rgb2gray转换成灰度图):
>> f = imread('D:\picture\素材\Dragon.jpg');
>> f = rgb2gray(f);
>> size(f)
ans =
225 225
- whos 函数可以查看变量属性:
>> whos f
Name Size Bytes Class Attributes
f 225x225 50625 uint8
- imfinfo(filename) 函数返回一个结构,其中包含了图像的全部信息:
imfinfo ('D:\picture\素材\Dragon.jpg')
ans =
包含以下字段的 struct:
Filename: 'D:\picture\素材\Dragon.jpg'
FileModDate: '18-Jun-2017 10:26:04'
FileSize: 14220
Format: 'jpg'
FormatVersion: ''
Width: 225
Height: 225
BitDepth: 24
ColorType: 'truecolor'
FormatSignature: ''
NumberOfSamples: 3
CodingMethod: 'Huffman'
CodingProcess: 'Sequential'
Comment: {}
提示:语句结尾出的“;”号是MLAB用于抑制输出的,若语句中没有分号,MATLAB会将该行指定的操作结果显示在屏幕上。
类和图像类型
MATLAB中用于图像处理的类
图像类型
- 灰度级图像(Gray-scale images)
- 二值图像(Binary images)
- 索引图像(Indexed images)
- RGB图像(RGB images)
灰度级图像
一幅灰度级图像是一个数据矩阵,矩阵的值表示灰度的浓淡。
二值图像
一幅二值图像是一个取值只有0和1的逻辑数组
注:islogical()函数可以判断一个数组是否是逻辑数组
islogical(C)
如果C是逻辑数组,则返回1,否则返回0。
通用的类转换语法
B = class_name(A)
其中class_name可以是im2uint8, im2uint16, im2double, im2single, mat2gray或者logical。
eg:
>> A = [1 2 3; 4 5 6; 7 8 9];
>> B = logical(A);
逻辑数组B是由数值数组A转化而来
一些重要的标准数组
>> A = true(4, 5)
A =
4×5 logical 数组
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
>> B = magic(4)
B =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
M函数编程
M文件
M文件由文本编辑器创建, 并以形式为filename.m的文件名储存。
M文件的组成部分:
- 函数定义行
- H1行
- 帮助文本
- 函数体
- 注释
函数定义行:一般形式 function[outputs] = name(inputs)。如果函数只有单个输出参量,可不使用括号直接列出。如果函数没有输出,则仅使用单词function,而不需要括号或等号。
H1行:这一行为M文件提供了非常重要的概要信息。
帮助文本:为函数提供注释和在线帮助
函数体:代码区域
注释:符号“%”后的非H1行或帮助文本的所有行
运算符
算数运算符:
注:图像算数函数(图像的大小和类型要相同)
关系运算符:
- 逻辑运算符:
数组索引
- 通过单一索引值(下标)访问
>> A = [1 3 5 7 9 ];
>> B = [2; 4; 6; 8; 10];
>> C = [1 2 3; 4 5 6; 7 8 9];
>> A(2)
ans =
3
>> B(2)
ans =
4
>> C(2)
ans =
4
通过运算结果可以看出,当数组为一维(向量)时,用下标是多少访问的就是第几个元素。当数组为二维(矩阵)时,访问的顺序如下图:
注:转置运算符(.’)可以实现行向量和列向量之间的转换
>> A = [1 2 3];
>> B = A.'
B =
1
2
3
- 使用冒号实现访问元素块
>> A = [1 2 3 4 5 6];
>> A(1 : 3)
ans =
1 2 3
>> A(3 : end)
ans =
3 4 5 6
>> A([1 4 5])
ans =
1 4 5
>> A(1 : 2 : end)
ans =
1 3 5
- 逻辑索引
>> A = [1 2 3; 4 5 6; 7 8 9]
A =
1 2 3
4 5 6
7 8 9
>> D = logical([1 0 0; 0 0 1; 0 0 0])
D =
3×3 logical 数组
1 0 0
0 0 1
0 0 0
>> A(D)
ans =
1
6
- 线性索引
对于一个M×N的矩阵,元素(r, c)可用单一下标r + M(c - 1)来访问,即A(2, 3)相当于A(8),参见上图。
代码优化
- 测速
函数1:
function y = sinfun1(M)
x = 0:M - 1;
for(k = 1:numel(x))
y(k) = sin(x(k) / (100*pi));
end
>> tic; sinfun1(100); toc
时间已过 0.033022 秒。
函数2(预分配)
function y = sinfun2(M)
x = 0:M - 1;
y = zeros(1, numel(x));
for k = 1:numel(x)
y(k) = sin(x(k) / (100*pi));
end
>> tic; sinfun2(20000); toc
时间已过 0.000920 秒。
>> tic; sinfun1(20000); toc
时间已过 0.003405 秒。
- 向量化和meshgrid函数
function f = twosin1(A, u0, v0, M, N)
f = zeros(M, N);
for c = 1:N
v0y = v0 * (c - 1);
for r = 1:M
u0x = u0 * (r - 1);
f(r, c) = A*sin(u0x + v0y);
end
end
>> timeit(@() twosin1(1, 1/(4*pi), 1/(4*pi), 512, 512))
ans =
0.0092
用meshgrid重写该函数
function f = twosin2(A, u0, v0, M, N)
r = 0:M - 1;
c = 0:N - 1;
[C, R] = meshgrid(c, r);
f = A*sin(u0*R + v0*C);
end
>> timeit(@() twosin2(1, 1/(4*pi), 1/(4*pi), 512, 512))
ans =
0.0057