MATLAB基本的使用方法归纳(图像,矩阵及函数)
标签: 杂谈 |
分类: matlab |
读取图像:用imread函数读取图像文件,文件格式可以是TIFF、JPEG、GIF、BMP、PNG等。比如
>> f = imread('chestxray.jpg');
读进来的图像数据被保存在变量f中。尾部的分号用来抑制输出。如果图片是彩色的,可以用rgb2gray转换成灰度图:
>> f = rgb2gray(f);
然后可以用size函数看图像的大小
>> size(f)
如果f是灰度图像,则可以用下面的命令把这个图像的大小赋给变量M和N
>> [M, N] = size(f);
用whos命令查看变量的属性
>> whos f
显示图像:用imshow显示图像
imshow(f, G)
其中f是图像矩阵,G是像素的灰度级,G可以省略。比如
>> imshow(f, [100 200])
图像上所有小于等于100的数值都会显示成黑色,所有大于等于200的数值都会显示成白色。pixval命令可以用来查看图像上光标所指位置的像素值。
pixval
例如
>> f = imread('rose_512.tif');
>> whos f
>> imshow(f)
如果要同时显示两幅图像,可以用figure命令,比如
>> figure, imshow(g)
用逗号可以分割一行中的多个命令。imshow的第二个参数用一个空的中括号:
>> imshow(h, [])
可以使动态范围比较窄的图像显示更清楚。
写图像。用imwrite写图像
imwrite(f, 'filename')
文件名必须包括指明格式的扩展名。也可以增加第三个参数,显式指明文件的格式。比如
>> imwrite(f, 'patient10_run1.tif', 'tif')
也可以写成
>> imwrite(f, 'patient10_run1.tif')
还可以有其他参数,比如jepg图像还有质量参数:
>> imwrite(f, 'filename.jpg', 'quality', q)
q是0到100之间的一个整数。对比不同质量的图像效果。用imfinfo命令可以查看一个图像的格式信息,比如
>> imfinfo bubbles25.jpg
可以把图像信息保存到变量中
>> K = imfinfo('bubbles25.jpg');
>> image_bytes = K.Width * K.Height * K.BitDepth / 8;
>> compressed_btyes = K.FileSize;
>> compression_ratio = image_bytes / compressed_bytes
数据类型。MATLAB的数据类型包括:
double 双精度浮点
uint8 无符号8位整数
uint16 无符号16位整数
uint32 无符号32位整数
int8 有符号8位整数
int16 有符号16位整数
int32 有符号32位整数
single 单精度
char 字符
logical 逻辑型(二值)
数据类型转换
B = data_class_name(A)
比如
>> C = [1.4 1.5]
>> D = uint8(C)
图像类型分为:
Intensity image 灰度图
Binary image 二值图
Indexed image 索引图
RGB image 彩色图
在灰度图中每个像素可以是整型、浮点型或者逻辑型。图像类型的像素类型可以转换
function to from
im2uint8 uint8 logical,uint8,uint16,double
im2uint16 uint16 logical,uint8,uint16,double
mat2gray double double
im2double double logical,uint8,uint16,double
im2bw logical uint8,uint16,double
比如
g = mat2gray(A, [Amin, Amax]);
g = mat2gray(A);
g = im2double(h);
g = im2bw(f, T)
其中A是浮点型的图像,Amin和Amax是浮点数的范围,h和f是任意类型的图像,T是分割的阈值。
数组(向量)索引:创建向量(数组):
>> v = [1 3 5 7 9 11 13]
用小括号对向量进行索引(取数组中的某个元素):
>> v(2)
转置(将行向量通过转置变成列向量):
>> w = v.'
取向量其中的一部分:
>> v(1:3) 第1个到第3个
>> v(2:4)
>> v(3:end) 第3个到最后一个
>> v(1:end)
>> v(:) 全部
>> v(1:2:end) 第1个到最后一个,每次增加2
>> v(end:-2:1) 最后一个到第1个,每次减2
其中end总是表示最后一个。
>> x = linspace(1, 5, 10)
>> v([1 4 5])
linspace函数产生一个范围内的平均分布。
矩阵索引:创建矩阵
>> A = [1 2 3; 4 5 6; 7 8 9]
取矩阵中的一个元素
>> A(2, 3)
取矩阵中的一行或者一列
>> C3 = A(:, 3)
>> R2 = A(2, :)
取矩阵中某些行某些列
>> T2 = A(1:2, 1:3)
对矩阵中某些元素进行赋值:
>> B = A;
>> B(:, 3) = 0
用end表示最后一行或者最后一列:
>> A(end, end) 最后一行最后一列
>> A(end, end-2) 最后一行倒数第三列
>> A(2:end, end:-2:1) 第2行到最后一行,最后一列到第一列,每次减2
>> E = A([1 3], [2 3]) 第1、3行,第2、3列
>> D = logical([1 0 0; 0 0 1; 0 0 0])
>> A(D) 取A中由D指定的位置上的元素
>> v = T2(:) 把矩阵变成一个向量
>> s = sum(A(:)) 求和
>> sum(sum(A))
可以把矩阵操作用在图像上
>> f = imread('filename');
>> fp = 矩阵列倒转
>> imshow(fp)
>> fc =
>> imshow(fc)
>> fs =
>> imshow(fs)
>> plot(f(512,:))
矩阵可以是多维的,用size看矩阵大小,用ndims命令常看矩阵的维数
>> size(A, 1)
>> ndims(A)
一些常用的矩阵
zeroes(M, N)
ones(M, N)
true(M, N)
false(M, N)
magic(M)
rand(M, N)
randn(M, N)
其中M、N表示矩阵的行数和列数。比如
>> A = 5 * ones(3, 3)
>> magic(3)
>> B = rand(2, 4)
函数:可以把一系列的MATLAB语句或者一个带参数的函数放在扩展名叫做m的文件中。一个带函数的m文件有一下部分组成
函数定义行
H1行
帮助部分
函数体
注释
函数定义行的格式是
function [outputs] = name(inputs)
比如要写一个函数计算两个图像的和以及乘积
function [s, p] = sumprod(f, g)
其中f和g是输入的图像,而s是和,p是乘积。返回值用中括号括起来,如果返回值只有一个,可以省略中括号。如果函数没有输出,则中括号和等号都可以省略。函数名字的命名规则和C语言是相同的。定义好的函数可以在命令行调用:
>> [s, p] = sumprod(f, g);
也可以被其它函数调用。如果只有一个返回值,调用时中括号也是可以省略的,比如
>> y = sum(x);
H1行是文本的第一行,是一个单行的注释,紧跟在函数定义行后面,之间不能有空行。比如
% SUMPROD Computes the sum and product of two images.
百分号开始的文字表示注释。当使用帮助命令
>> help function_name
时,这个H1行会被首先显示出来。如果使用lookfor命令,则会在所有H1行中查找指定的关键字。这一行应该提供这个函数功能的一个概述。帮助部分是紧跟在H1后的文本块,中间没有空行,用来提供对这个函数更详细的帮助说明。在使用help命令时会显示所有这部分内容。这部分内容由注释语句构成,全部由%开始。接下来第一个非注释语句表示函数体的开始。函数体包含进行计算的语句和给返回值赋值的语句。函数题中的所有注释(百分号开始的行)被认为是普通的注释,不是H1或者帮助部分。m文件可以用任何文本编辑器创建和编辑,只要用.m扩展名保存在MATLAB可以搜索到的路径里面。另一个创建和编辑函数的方法是在命令行输入edit命令,比如
>> edit sumprod
这命令会编辑已经存在的sumprod.m文件,如果没有则自动在当前目录中创建一个sumprod.m并开始编辑。
运算符。运算符可以分为算术运算符,关系运算符和逻辑运算符。算术运算符分为矩阵算术运算符和数组算术运算符。
+ 矩阵和数组加法 plus(A, B) a+b, A+B
- 矩阵和数组减法 minus(A,B) a-b, A-B
.* 数组乘法 times(A,B) C=A.*B, 意味着C(I,J) = A(I,J)*B(I,J)
* 矩阵乘法 mtimes(A,B) A*B, 表示线性代数中的矩阵运算,或者a*A
./ 数组右除 rdivide(A,B) C=A./B, 意味着C(I,J)=A(I,J)/B(I,J)
.\ 数组左除 ldivide(A,B) C=A.\B, 意味着C(I,J)=B(I,J)/A(I,J)
/ 矩阵右除 mrdivide(A,B) A/B 意味着A*inv(B), inv是矩阵求逆
\ 矩阵左除 mldivide(A,B) A\B 意味着inv(A)*B
.^ 数组指数 power(A, B) C=A.^B,意味着C(I,J)=A(I,J)^B(I,J)
^ 矩阵指数 mpower(A,B) 请查看帮助
.' 向量和矩阵转置 transpose(A) A.'
' 复数的共轭 ctranspose(A) A'
+ 单目加号 uplus(A) +A 与0+A相同
- 单目负号 uminus(A) -A 与0-A相同
图像处理工具包还提供其他一些算术运算
imadd 两个图像相加,或者一个图像加上一个常量
imsubstract 两个图像相减,或者一个图像减掉一个常量
immultiply 两个图像相乘,或者一个图像乘上一个常量
imdivide 两个图像相除,或者一个图像除以一个常量
imabsdiff 两个图像的差的绝对值
imcomplement 求一个图像的反色图
inlincomb 求一组图像的线性组合
关系运算符包括
<
<=
>
>=
==
~=
关系运算符的结果是逻辑型的矩阵,比如
>> A = [1 2 3; 4 5 6; 7 8 9]
>> B = [0 2 4; 3 5 6; 3 4 9]
>> A == B
>> A >= B
如果关系运算符两边都是矩阵,则要求两边的矩阵是同样大小的。或者一边是矩阵一边是常数,或者两边都是常数,那也是可以。
>> A > 3
>> 3 ~= 4
逻辑运算符包括与、或、非三个运算
& AND
| OR
~ NOT
在matlab中非0被认为是真,0被认为是假。比如
A = [1 2 0; 0 4 5]
B = [1 -2 3; 0 1 1]
>> A & B
MATLAB还有其它一些逻辑运算函数:
xor 异或
all 如果一整列都是真,则结果是真
any 如果一整列只要有一个是真,则结果是真
比如
>> xor(A, B)
>> all(A)
>> any(A)
>> all(B)
>> any(B)
一些重要的常量
ans
eps
i(或者j)
NaN或者nan
pi
realmax
realmin
computer
version
MATLAB中一般常量的写法
3
-99
0.00001
9.6397238
1.60210e-20
6.02252e23
1i
-3.14159j
3e5j
控制流。包括
if if和else, elseif组合,条件执行一组语句
for 指定次数重复执行一组语句
while 按条件反复执行一组语句
break 终止for或者while循环
continue 马上开始下一次for或者while循环
switch switch和case,otherwise结合,按照条件值的不同执行不同的语句块
return 终止当前函数,返回到调用它的地方
try...catch 捕获异常状况
if语句
if expression_r1
statements1
elseif expression_r2
statements2
else
statements3
end
for循环
for index = start:increment:end
statements
end
比如
count = 0;
for k = 0:0.1:1
count = count +1
end
while循环
while expression_r
statements
end
比如
a = 10;
b = 5;
while a
a = a - 1;
while b
b = b - 1;
end
end
switch语句
switch switch_expression_r
case case_expression_r
statements
case {case_expression_r1, case_expression_r2}
statements
otherwise
statements
end
比如
switch newclass
case 'uint8'
g = im2uint8(f);
case 'uint16'
g = im2uint16(f);
case 'double'
g = im2double(f);
otherwise
error('Unknown or improper image class.')
end
例子:写一个函数计算一幅灰度图像所有像素的平均值
function av = average(A)
%AVERAGE Computes the average value of an array
% AV = AVERAGE(A) computes the average value of input array, A,
% which must be a 1D or 2D array.
% Check the validity of input.
if ndims(A) > 2
error('The dimensions of the input cannot exceed 2.')
end
% Computes the average
av =
例子:比较各种不同的JPEG质量下的图像质量
for q = 0:5:100
filename = sprintf('series_%3d.jpg', q);
imwrite(f, filename, 'quality', q);
end
其中sprintf语句和c语言的fprintf语句用法类似。例子:写一个函数从一个图像中取出一个矩形的子图。
function s = subdim(f, m, n, rx, cy)
%SUBDIM Extracts a subimage, s, from a given image, f.
% The subimage is of size m-by-n, and the coordinates of its top, left
% corner are (rx, cy).
s = zeros(m, n);
rowhigh = rx + m - 1;
colhigh = cy + n - 1;
xcount = 0;
for r = rx:rowhigh
xcount = xcount + 1;
ycount = 0;
for c = cy:colhigh
ycount = ycount + 1;
s(xcount, ycount) = f(r, c);
end
end
实际上这个功能可以用一个matlab语句就可以实现了。
循环优化。一些循环可以被转换成同样向量计算来代替,比如f(x)=Asin(x/2pi),生成一个向量包含一组函数的值:
for x = 1:M
f(x) = A*sin((x-1)/(2*pi));
end
可以用下面两个语句来代替
x =
f = A*sin(x/2(*pi))
向量运算要比循环快得多。对于二维的情况,MATLAB提供了一个meshgrid函数
[C, R] = meshgrid(c, r)
比如
>> r = [0 1 2];
>> c = [0 1];
>> [C, R] = meshgrid(c, r)
>> h = R.^2 + C.^2
例子:f(x, y) = Asin(ux + vy),生成一个矩阵,包含这个函数的值:
function [rt, f, g] = twodsin(A, u0, v0, M, N)
%TWODSIN compare for loops vs vectorization
% The comparision is based on implementing the function
% f(x, y) = Asin(u0x+v0y) for x = 0, 1, 2,..., M-1, and
% y = 0, 1, 2, ..., N-1. The inputs to the function are
% M and N and the constants in the function.
tic
for r = 1:M
u0x = u0*(r-1);
for c = 1:N
v0y = v0*(c-1)
f(r, c) = A*sin(u0x + v0y);
end
end
t1 = toc;
tic
r =
c =
[C,R] = meshgrid(c, r);
g = A*sin(u0*R + v0*C)
t2 = toc;
rt = t1/t2;
运行这个例子可以看出,向量计算至少比循环要快30倍。如果只是针对图像的一部分进行操作,可以简单的提取出来,比如
rowhigh = rx + m - 1;
colhigh = cy + n - 1;
s =
同样功能的程序,这个写法比前面例子看到的写法要快1000倍。
用户交互。函数disp用来提示用户一些信息。比如
>> A = [1 2; 3 4];
>> disp(A)
>> sc = 'Digital Image Processing.';
>> disp(sc)
>> disp('This is another way to display text.')
input函数用来提示用户输入某些值:
t = input('message')
这个函数可以显示message,并等待用户输入一个值,并存到t中。输入的值可以是MATLAB允许的任何类型的值。而如下的格式只接受字符串输入
t = input('message', 's')
如果字符串中包含的都是数字,则可以用函数str2num进行转换
n = str2num(t)
比如
>> t = input('Enter your data: ', 's')
>> class(t)
>> size(t)
>> n = str2num(t)
>> size(n)
>> class(n)
如果混合输入字符串和数值,可以全部按照字符串读入,再使用字符串处理函数strread,比如:
>> t = '12.6, x2y, z';
>> [a, b, c] = strread(t, '%f%q%q', 'delimiter', ',')
>> d = char(b)
其中%f表示浮点数,%q表示字符串。delimiter参数表示分割符。函数strcmp用来比较字符串,如果两个字符串相等返回真,否则返回假。lower函数可以把字符串中的大写字母全部变成小写,upper函数可以把字符串中所有小写字母全部变成大写。
Cell数组和结构体。Cell数组是指数组的元素本身还是一个数组,比如
>> c = {'gause', [1 0; 0 1], 3}
>> c{1}
>> c{2}
>> c{3}
结构体和Cell数组类似,但是其中的元素是用一个名字去访问的,比如
>> S.char_string = 'gause';
>> S.matrix = [1 0; 0 1];
>> S.scalar = 3;
>> S.matrix
实验任务
MATLAB 没有提供一个函数来确定数组的每个元素是不是整数(即...,-2,-1,0,1,2,...)。写一个函数来实现这个功能,并满足下面的格式:
function I = isinteger(A)
%ISINTEGER Determines which elements of an array are integers.
% I = ISINTEGER(A) returns a logical array, I, of the same size
% as A, with 1s (TRUE) in the locations corresponding to integers
% (i.e., . . . -2 -1 0 1 2 . . . )in A, and 0s (FALSE) elsewhere.
% A must be a numeric array.
要求不能使用while或者for循环。提示:使用floor函数。如果你要做到能够处理复数,那么可以使用real和imag函数。
MATLAB没有提供一个函数用来确定数组的每个元素是不是偶数(即...,-4,-2,0,2,4,...)。写一个函数来实现这个功能,并满足下面的格式:
function E = iseven(A)
%ISEVEN Determines which elements of an array are even numbers.
% E = ISEVEN(A) returns a logical array, E, of the same size as A,
% with 1s (TRUE) in the locations corresponding to even numbers
% (i.e., . . . -3, -1, 0, 2, 4, . . . )in A, and 0s (FALSE) elsewhere.
% A must be a numeric array.
要求不能使用while或者for循环。提示:使用floor函数。
MATLAB没有提供一个函数用来确定数组的每个元素是不是奇数(即...,?3,?1,1,3,...)。写一个函数实现这个功能,并满足下面的格式:
function D = isodd(A)
%ISODD Determines which elements of an array are odd numbers.
% E = ISODD(A) returns a logical array, D, of the same size as A,
% with 1s (TRUE) in the locations corresponding to odd numbers
% (i.e., . . . -3, -1, 1, 3, . . . )in A, and 0s (FALSE) elsewhere.
% A must be a numeric array.
要求不能使用while或者for循环。提示:使用floor函数。
写一个函数满足下面的规定:
function H = imcircle(R, M, N)
%IMCIRCLE Generates a circle inside a rectangle.
% H = IMCIRCLE(R, M, N) generates a circle of radius R centered
% on a rectangle of height M and width N. H is a binary image with
% 1s on the circle and 0s elsewhere. R must be an integer >= 1.
你的程序应该检查R的合理性,使它能够在矩形的内部。要求不能使用for或者while循环。提示:使用函数meshgrid和floor函数。
这个实验主要目的是学习如何显示和改变目录,并利用目录信息来读取图像。写一个函数满足下面的规定:
function [I, map] = imagein(path)
%IMAGEIN Read image in from current-working or specified directory.
% I = IMAGEIN displays a window containing all the files in the
% current directory, and saves in I the image selected from the
% current directory.
% [I, MAP] = IMAGEIN variable MAP is required to be an output
% argument when the image being read is an indexed image.
% [ . . .] = IMAGEIN('PATH') is used when the image to be read
% resides in a specified directory. For example, the input
% argument 'C:\MY_WORK\MY_IMAGES' opens a window showing
% the contents of directory MY_IMAGES. An image selected from
% that directory is read in as image I.
提示:使用在线帮助来熟悉cd,pwd,uigetfile函数的使用。或者也可以采用fullfile函数来代替cd函数