第一章 绪言

第一章 绪言

-

  • MATLAB与数字图像处理

  • 数字图像表示

    • 坐标约定

    • 作为矩阵的图像

  • 图像输入与显示

  • 类和图像类型

    • 图像类型

    • 灰度级图像

    • 二值图像

  • M函数编程

    • M文件

    • 运算符

    • 算数运算符

    • 关系运算符

    • 逻辑运算符

    • 数组索引

    • 一些重要的标准数组

    • 函数句柄、单元数组和结构

  • 代码优化

一.MATLAB与数字图像处理

MATLAB是面向矩阵的语言,是Matrix Laboratory(矩阵实验室)的缩写,其设计初衷是成为处理矩阵和线性代数的软件。

数字图像处理就是借助计算机处理数字图像。

数字图像:一幅图像可以定义为一个二维函数f(x, y),其中x和y是空间坐标,而f再任意坐标(x, y)处的幅度称为图像在该点处的==亮度或灰度==。当x、y和f的幅值都是有限的离散值时,称该图像为数字图像。

二.数字图像表示

1.灰度级通常指单色图像的亮度。

2.彩色图像是由多幅单色图像组合而成。


RGB彩色系统中,一副彩色图像是由三幅单色图像组成的,即红(R)、绿(G)、蓝(B)原色(或分量)图像。
坐标约定
  • 空间坐标:图像的平面远点都被定义在(x, y)=(0, 0)处。==x的范围是从0到M - 1,y的范围是从0到N - 1,以整数递增。==

  • 像素坐标:用(r, c)表示行与列,该坐标系的原点在(r, c) = (1, 1)处。==r的范围是从1到M,c的范围从1到N,以整数递增。==

作为矩阵的图像

矩阵中每一个元素都称为图像元素、图画元素或像素。

矩阵是二维的,而阵列可是任意有限维的。

三.图像输入与显示

  • imread将图像读入环境中

imread(‘filename’)


f = imread('chestxray.jpg')

imread支持多数流行的图像/图形格式,包括JPEG、JPEG 2000和TIFF。

  • imshow将图像显示在MATLAB桌面上

imshow(f)

当有两个图像时,要保留第一幅图像并输出第二幅图像,可使用


figure, imshow(g)
  • 图像被函数写入当前目录

imwrite(f, ‘filename’)

注意:imwrite还可以有其他参数,取决于将被写的文件的格式。

仅适用于tif图像的一种更为通用的imwrite语法形式为

imwrite(g, ‘filename.tif’, ‘compression’, ‘parameter’,…’resolution’, [colres rowres])

仅适用于JPEG的一种更同通用的imwrite语法形式为

imwrite(f, ‘filename.jpg’, ‘quality’, q)

  • 图像的全部信息存在一个结构中

imfinfo(‘filename’)

提示:语句结尾出的“;”号是MLAB用于抑制输出的,若语句中没有分号,MATLAB会将该行指定的操作结果显示在屏幕上。

四.类和图像类型

image

  • 图像类型

    • 灰级图像(Gray-scale images)

    • 二值图像(Binary images)

    • 索引图像(Indexed images)

    • RGB图像(RGB images)

灰级图像

一幅灰度级图像是一个数据矩阵,矩阵的值表示灰度的浓淡。

二值图像

一幅二值图像取值只有0和1的逻辑数组。


A = [1 0 1; 0 1 0; 1 0 1]

imshow(A, 'InitialMagnification', 'fit');

只有0和1组成的矩阵可以形成一个二值图像。

image

  • 判断数组是否是logical类

islogical(A)


B = logical(A)

islogical(A)

islogical(B)

结果第一行将是将B设定为3 x 3的logical数组,和A的值相同。A不是logical类,ans = 0;B是logical类,ans = 1。

  • 逻辑数组转化数值数组

B = class_name(A)

其中class_name可以是im2uint8、im2uint16、im2double、im2single或mat2gray。

g = mat2gray(A, [Amin, Amax])

Amin和Amax的作用:若A中的值小于Amin,则在g中变为0;若A中的值大于Amax,则在g中变为1.

g = mat2gray(A)

将Amin和Amax的值设定为A中的实际最小值和最大值。

五.M函数编程

  • M文件

函数形式

function [outputs] = name(inputs)

以计算两幅图像的和与积为例


function [s, p] = sumprod(f, g)

s = plus(f, g);

p = times(f, g);

image

image

help function_name

显示该函数

算数运算符

image

关系运算符

A == B

A==B:生成一个与A和B维数相同的逻辑数组,当A与B的相应元素匹配是位置取1,其余取0。

大致与其它语言的关系运算符类似。

逻辑运算符

1.AND—>&

2.OR—->|

3.NOT—>~

  • 逻辑函数

xor(异或)

all:一个向量中的所有元素都非零,函数返回1,否则返回0.

any:一个向量中任何元素都非零,函数返回1,否则返回0,该函数在矩阵中按列操作。

数组索引

>> v = [1 3 5 7 9]



v =



     1     3     5     7     9



>> w = v.'



w =



     1

     3

     5

     7

     9



>> v(1:3)  %坐标约定从1开始,如果改成v(0:3)会提示错误,索引必须为正整数或逻辑值。这和一般我们学过的语言不相同



ans =



     1     3     5



>> v(3:end)



ans =



     5     7     9



>> v([1 4 5])  %向量作为索引



ans =



     1     7     9



>> v(1:2:end)  %从1开始,依次加2



ans =



     1     5     9
  • 矩阵索引

>> A = [1 2 3; 4 5 6; 7 8 9]



A =



     1     2     3

     4     5     6

     7     8     9



>> A(2,:)  %第二行的所有值



ans =



     4     5     6



>> sum(A(:, 3))   %第三列的所有值的和



ans =



    18
  • 逻辑索引

>> 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
一些重要的标准数组

image


>> A = 2 * ones(3, 3)  %元素都是2的一个3 x 3的矩阵



A =



     2     2     2

     2     2     2

     2     2     2



>> B = rand(2, 5)  %随机生成2 x 5的矩阵



B =



    0.8147    0.1270    0.6324    0.2785    0.9575

    0.9058    0.9134    0.0975    0.5469    0.9649

函数句柄、单元数组和结构

函数句柄
  • 命名函数句柄

>> f = @sin



f =



  包含以下值的 function_handle:



    @sin



>> f(pi/4)



ans =



    0.7071



>> sin(pi/4)



ans =



    0.7071
  • 匿名函数句柄

(input-argument-list) expression


>> g = @(x) x.^2



g =



  包含以下值的 function_handle:



    @(x)x.^2



>> g(3)



ans =



     9
单元数组

单元矩阵提供了一种在一个变量名下组合一套对象的方法

C = {f, b, char_arry}


>> f = imread('image.tif');

>> b = [1 2 3; 4 5 6]



b =



     1     2     3

     4     5     6



>> char_array = {'area', 'centroid'}



char_array =



  1×2 cell 数组



    {'area'}    {'centroid'}



>> C = {f, b, char_array}



C =



  1×3 cell 数组



    {664×840 uint8}    {2×3 double}    {1×2 cell}



>> C{3}



ans =



  1×2 cell 数组



    {'area'}    {'centroid'}



>> C(3)



ans =



  1×1 cell 数组



    {1×2 cell}

花括号是查看单元的一个元素的全部内容,圆括号是给出该变量描述。

结构

function s = image_stats(f)

s.dm = size(f);   %size(f)返回二维图像f的行数和列数

s.AI = mean2(f);   %计算f中元素的平均值

s.AIrows = mean(f, 2);   %mean(v)返回v元素的平均值,若A是一个矩阵,则将A当做向量来处理,返回平均值的一个行向量

s.AIcols = mean(f, 1);

调用函数


>> s = image_stats(f)



s = 



  包含以下字段的 struct:



        dm: [664 840]

        AI: 192.5988

    AIrows: [664×1 double]

    AIcols: [1×840 double]

s显示的是这张图片的基本信息。

六.代码优化

优化有两种重要方法:

1.预分配数组

2.向量化循环

  • 测量函数运行时间

tic;函数;toc;

预分配数组

%正常函数形式

function y = sinfun1(M)

x = 0:M - 1;

for k = 1:numel(x)              %numel(x)给出数组的元素数

    y(k) = sin(x(k) / (100 * pi));

end

%预分配函数形式

function y = sinfun2(M)

x = 0 : M - 1;

y = zeros(1, numel(x));    %zeros(M, N)生成一个double类的全0的M x N矩阵。

for k = 1 : numel(x)

    y(k) = sin(x(k) / (100 * pi));

end

预分配可以帮助我们减少存储器碎片。


>> tic;sinfun1(100);toc

时间已过 0.000430 秒。

>> tic;sinfun2(100);toc

时间已过 0.000366 秒。

上面是两个函数的时间比较,可以看出时间的差距。

  • 可靠的时间测量

使用tic;toc;如果分行键入语句,那么时间测量量将包括键入后两行所要求的时间。这样会出现时间测量的不准确。所以使用timeit函数。

s = timeit(f)


>> M = 100;

>> f = @()sinfun1(M);

>> timeit(f)



ans =



   8.1831e-05



>> g = @()sinfun2(M);

>> timeit(g)



ans =



   6.5239e-06

MATLAB向量化是完全消除循环的一种技术,但其运行时间与有循环的运行时间大致相同。

向量化循环(meshgrid函数)

%两个嵌套for循环

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

%使用meshgrid函数重写该函数

function f = twosin2(A, u0, v0, M, N)

r = 0:M - 1;   %Row coordinates

c = 0:N - 1;   %Column coordinates

[C, R] = meshgrid(c, r);

f = A * sin(u0 * R + v0 * C);

在对时间进行比较,发现使用meshgrid函数时,用的时间相对较少,加快了运行速度


>> timeit(@()twosin1(1, 1/(4*pi), 1/(4*pi), 512, 512))



ans =



    0.0075



>> timeit(@()twosin2(1, 1/(4*pi), 1/(4*pi), 512, 512))



ans =



    0.0054


  • 显示的图片

>> f = twosin2(1,1/(4*pi),1/(4*pi),512,512);

>> imshow(f, [])

image


>> f = twosin2(1,1/(4*pi),1/(4*pi),512,512);

>> imshow(f)

image

两张图片显示的不一样,但是都是f,原因就是因为imshow(f)直接显示f图像;imshow(f,[])显示的是灰度级数归一化后的图像,就相当于f = mat2gray(f)。

猜你喜欢

转载自blog.csdn.net/qq_39227338/article/details/80024279