数字图像处理完整实践1--基础知识

写在前面

  • 关于参考材料:本系列博客参考学习经典教材《Digital Image Processing Using MATLAB》所总结的笔记,如有侵权,还请麻烦联系作者删除。
  • 关于使用建议:本系列博客与教材相似,自成体系。同时加入了作者学习所遇到的困惑与心得。可以作为图像处理、计算机视觉爱好者的辅助指南。也竭力让其更易懂,从而帮助广大读者更好地掌握传统的图像处理技术。
  • 关于实验平台:本系列博客基于Matlab2013(Window7)以上的版本做实验。
  • 关于提问与反馈:在本系列博客阅读中,读者若产生相关疑问,可在评论中提问,本人非常荣幸能与大家共同探讨。我也将实时更新博客,如有错误,欢迎大家批评指正。

1.数字图像与Matlab(IPT)基础知识


Matlab语言简洁表示+IPT(理想的软件原型环境):大量图像处理操作可按简洁明了的编码方式进行。
本博客为后续内容的基础,重要内容有

  • Matlab表示法的基本知识
  • IPT(扩展Matlab数值计算能力的函数集/图像处理工具箱)基本属性和函数
  • 增强IPT的程序设计概念

1.1数字图像的表示

图像定义:二维函数 f ( x , y ) f(x, y) f(x,y)。其中 x x x y y y是空间(平面)坐标, f f f在任何坐标点 ( x , y ) (x, y) (x,y)处的振幅,也就是图像在该点的亮度(或是黑白图像中的灰度)。【连续的二维函数】
其中,彩色图像的组成元素是单个二维图像 f ( x , y ) f(x, y) f(x,y)。如RGB彩色图像由三幅独立的分量二维图像(红、绿、蓝)组成。
数字图像定义:当图像 f f f的坐标 x x x y y y分量和振幅都是有限且离散的量。【二维数组(实数矩阵)----也及后续表示为二维数组的都为数字图像】
因为图像关于 x x x y y y坐标以及振幅连续,所以需要通过取样(坐标值数字化),量化(振幅数字化),将图像装换成数字图像。

1) 坐标约定
数据图像表示为一个实数矩阵如下图2.1所示(主要两种不同的坐标约定)。
其中每个坐标点 ( x , y ) (x, y) (x,y)(或 ( r , c ) (r, c) (r,c))不是图像在取样时的实际物理坐标值,只表示第几行的第几个取样。
还有一种较少用的IPT坐标约定,与 ( x , y ) (x, y) (x,y)正好相反,表示为 ( y , x ) (y, x) (y,x),其中 y y y表示行, x x x表示列。
图片来源于材料
2) 图像的矩阵表示
数字图像的数据化图像函数表示如下:
图片来源于材料
其中等式右边是由定义给出的一幅数字图像。该数组的每一个元素都称为像元图元像素。(为了便捷,默认称数字图像及其元素为图像和像素)
同样,数字图像在Matlab中可表示为矩阵如下所示:
图片来源于材料

1.2读取图像(imread)

  • 将图像读入Matlab环境:f = imread( ‘filename’ );
    在命令行窗口,且无需赋值给其他变量时,可直接使用imread filename;。其中若去掉封号,会将运行结果直接输出在命令行窗口。
  • 获取图像的行数M和列数N:[M, N] = size(f);
  • 获取图像的附加信息:whos f
    此命令本身就是要将信息输出到命令行窗口,故加不加封号都无影响。且不同的Matlab版本输出的附加信息并不相同。图像格式等相关信息如表2.1所示:
    在这里插入图片描述
    例子:将任意图片bk.png拷贝到Matlab当前工作路径,便可按以下方式输入命令进行实验。
>> f=imread('bk.png');
>> size(f)
ans =
   279   253     3
>> whos f
  Name        Size                Bytes  Class    Attributes
  f         279x253x3            211761  uint8  

1.3显示图像(imshow)

显示在Matlab桌面上的图像:imshow
常用的选项如下所示:

  • imshow(f):显示图像数组f,默认灰度级数为256(像素取值范围[0, 255])。
  • imshow(f, [low high]):显示图像数组f,其中将各灰度取值小于等于low的显示为黑色,大于等于high的显示为白色。介于low和high之间的值以默认的技术显示为中等亮度值。其中,imshow(f, [ ]) 表示图像数组f按原有的灰度级数显示(特别是针对动态范围较小或既有正值又有负值的图像)。
    可通过在命令行窗口输入help imshow或查询相关帮助文档,获取更多imshow使用方法。

例子:加载一个灰度图tree.png,并按照如下命令执行。

>> tree = imread('tree.png');
>> whos tree
Name        Size              Bytes  Class    Attributes
  tree      467x533            248911  uint8              
>> imshow(tree),figure,imshow(tree, [98 100]),figure,imshow(tree,[])

最后一行命令所显示的结果如下所示(配合使用逗号和命令figure可同时不覆盖地显示多幅图片):
在这里插入图片描述

1.4保存图像(imwrite)

-将Matlab桌面上的图像写到磁盘上:imwrite
不同的文件格式有不同的参数,常用的选项如下所示:

  • 通用语法imwrite(f, filename):其中,filename为路径+文件名+扩展名(表2.1支持的)的字符串组合,将图像f写入filename指定的磁盘位置。
  • 只适用于JPEG格式的语法imwrite(f, filename, ‘quality’, q):q为取值范围为[0, 100]的整数(q越小,图像退化越严重)。
    例子:压缩jpg图像及imfinfo的使用。
    >> imwrite(tree, './tree50.jpg', 'quality', 50)
    >> imwrite(tree, './tree25.jpg', 'quality', 25)
    >> imwrite(tree, './tree15.jpg', 'quality', 15)
    >> imwrite(tree, './tree5.jpg', 'quality', 5)
    >> imwrite(tree, './tree0.jpg', 'quality', 0)
    >> imwrite(tree, './tree.jpg')
    >> imfinfo tree.jpg %了解所实现的压缩并获得图像文件的其它详细信息
    ans = 
           Filename: 'D:\demo\tree.…'
            FileModDate: '02-Jul-2020 11:07:09'
               FileSize: 34873
                 Format: 'jpg'
          FormatVersion: ''
                  Width: 533
                 Height: 467
               BitDepth: 8
              ColorType: 'grayscale'
        FormatSignature: ''
        NumberOfSamples: 1
           CodingMethod: 'Huffman'
          CodingProcess: 'Sequential'
                Comment: {}
    >>%使用imfinfo计算图像压缩比
    >> K = imfinfo('tree.jpg') ;
    >> image_bytes = K.Width*K.Height*K.BitDepth/8;
    >> compressed_bytes = K.FileSize;
    >> compression_ratio = image_bytes/compressed_bytes
    compression_ratio =
     				7.1376
    
    按照不同的q值输出的结果如下所示(q=15或q=0时,图像退化严重):
    在这里插入图片描述
  • 只适用于tif格式的语法imwrite(f, filename, ‘compression’, ‘parameter’, ‘resolution’, [colres rowres]):其中parameter的取值主要有3种,'none’表示无压缩,'packbits’表示比特包压缩, 'ccitt’表示ccitt压缩 。[colres rowres]分别以每单位(如每英寸)中的点数给出图像的列分辨率和行分辨率(默认为[72, 72])。
    例子:利用无压缩,将图像tree.jpg从分辨率96dpix96dpi,像素大小为467x533(可得出图像大小为4.86x5.55英寸)减小为像素不变,大小为1x1.5英寸的tree.tif图像。
    	>> tree= imread('tree.jpg');
    	>> colres = round(467/1);
    	>> rowres = round(533/1.5);
    	>> imwrite(tree, 'tree.tif', 'compression', 'none', 'resolution', [colres, rowres])
    
    原图与写出后的图像如下所示:
    在这里插入图片描述
  • 只适用于tif格式的语法imwrite(f, filename, ‘compression’, ‘parameter’, ‘resolution’, [colres rowres])

1.5数据类(Data class)

数字图像的像素值用Matlab、IPT程序表示可用的数据类(数据类型)。
其中,像素的坐标都是整数的。
图片来源于材料
其中double类最常用;
unit8也常用(特别是从存储设备读取数据时);
logical和使用较少的unit16构成本书集中讨论的基础数据类。

1.6图像类型(Image type)

工具箱支持的图像类型有:
1)亮度图像(Intensity images)
表示为一个数据矩阵,规定双精度型归一化的像素取值范围是[0, 1]。

2)二值图像(Binary images)
表示为一个取值只有0和1的逻辑数组。在Matlab中具有特殊意义,仅仅包含0和1的其他类型数组不认为是二值图像的表示。
将其他类型数组转化为逻辑数组,可使用 logical() 函数(非零数值变为逻辑1)。通过 islogical() 来判断数组是否为逻辑数组。

#注意#大多数单色图像的处理运算通过以上两种图像类型来进行。以下两类图像见后续博客。

3)索引图像(Indexed images)
4)RGB图像(RGB images)

#注意#一幅数字图像由图像类型和数据类表征。如“unit 8 亮度图像”,“double 亮度图像”。

1.7数据类与图像类型间的转换

1.7.1数据类间的转换

数据类的转换遵循编程语言类型转换的一贯做法,通过数据类名,直接转换为想要的类型。
例如:常见将unit8类数组A转换为双精度数组B,可通过简单命令B=double(A)
#注意# 记住2.5中数据类表2.2的取值范围。若将取值范围大的数据类转换为小的,一般先进行缩放。

1.7.2图像类和类型的转换

释义:一个图像采用一种图像类型表示时,可以输入为一种或多种数据类的数组。可以使用本节提供的函数,进行数组的数据类转换。这个操作有时不会改变图像类型, 有时会。

表2.3列举了IPT中进行单色图像类和类型间的转换函数(彩色图像见后续博客)
在这里插入图片描述

  • im2uint8(f):检测出输入的图像数据类,并进行所有必要的缩放,将输入转换为uint8类。

  • im2uint16(f):类比于im2uint8(f)。

  • mat2gray(f, [fmin, fmax]):把一个double类的任意图像数组分f转换成取值范围为[0,1](0为黑色,1为白色)的归一化double数组。参数fmin和fmax是为了在转换时,将f中小于fmin的值转换为0,将f中大于fmax的值转换为1。如果不填写fmin和fmax,则默认f中最小值为fmin,最大值为fmax。

  • im2double(f):将输入转换为范围[0, 1]间的double类。若输入的已经是double类的,则返回相同的数组(不改变取值范围,此时建议用mat2gray方法)。

  • im2bw(f, T):将一幅亮度图像f进行所有必要的缩放(如输入为uint8,默认将所有元素值除255),转换为一幅二值图像。T为阈值(必须取值在0与1之间,不人为指定T时,默认为0.5),f中小于T的转换为0,其它转换为1。输入类型为logical的则输出相同的数组。将二值图像转为亮度图像则可使用以上四个函数。

    例子:

    >> f = [1, 2 ; 3, 4] %默认为double类型
    f =
         1     2
         3     4
    >> g = mat2gray(f) %将f的取值范围变为[0, 1]
    g =
             0    0.3333
        0.6667    1.0000
    >> gb = im2bw(g, 0.6)%去阈值为0.6,达到将f中1,2转为0的二值图像gb
    gb =
         0     0
         1     1
    >> gb = f > 2 %直接使用关系运算符生成二值数组
    gb =
         0     0
         1     1
    >> gbv = islogical(gb) %使用islogical判断gb是否为二值数组
    gbv =
         1
    >> gbd = im2double(gb) %将gb转换为值为0和1的double类数组
    gbd =
         0     0
         1     1
    

1.8 数组索引

主要关注一维和二维数组(向量和矩阵)的基本索引操作。

1.8.1向量索引

行向量rV,列向量cV,则常用向量索引操作有。
基础索引rV(i)/cV(i):提取行向量rV(或列向量cV)第i个元素。i取值从1开始。
向量转置(.’): rV.’ = cV
向量切片rV(start:step:end):在rV中,从索引start到索引end处,每隔step步,提取一个。
linspace(x1, x2, n): 以坐标(1,x1)与(n,x2)建立一条直线函数 f ( x ) f(x) f(x),并分别提取 f ( x ) , x = [ 1 , 2 , . . . , n ] f(x), x=[1,2, ... , n] f(x),x=[1,2,...,n]的值。当输入n=1,返回x2;输入n=2,返回x1,x2。
向量以向量为索引rV([i, j, k]):提取行向量rV第i,第j,第k个元素。

>> rV = [1 2 3 4 5] 
rV =
     1     2     3     4     5
>> rV(3)  %基础索引rV(i)/cV(i)
ans =
     3
>> cV = rV.' %向量转置(.')
cV =
     1
     2
     3
     4
     5     
>> rV(2:4) %向量切片
ans =
     2     3     4
>> rV(2:end) %end为内置变量,表示最后一个元素索引
ans =
     2     3     4     5
>> rV(:)  %不论rV(:)、cV(:),全部返回所有元素组成的列向量
ans =
     1
     2
     3
     4
     5
>> rV(1:end)  %行向量返回行向量,列向量返回列向量
ans =
     1     2     3     4     5     
>> rV(1:2:end) %正序隔步提取元素
ans =
     1     3     5
>> rV(end:-2:1) %逆序隔步提取元素
ans =
     5     3     1     
>> x = linspace(1, 10, 3)  %线性返回值
x =
    1.0000    5.5000   10.0000
>> rV([1, 3, 4]) %向量以向量为索引,不论传入的是行向量,还是列向量,都会转置后在索引
ans =
     1     3     4

1.8.2矩阵索引

矩阵索引操作就要是对向量索引操作的扩展,分别对矩阵A(row, col)分别作行向量索引和列向量索引操作。两种区别于向量索引的矩阵操作形式为:
以逻辑矩阵D作为矩阵A的索引矩阵A(D):提取逻辑矩阵D中非0元素对应位置的矩阵A中的元素。逻辑矩阵D的大小要和矩阵A相等。
A矩阵的冒号(:)运算:A(: )、A(8)等都是先将矩阵以每列拼接成一个列向量,而后,进行列向量切片操作。A(2:3)、A(1:end)等都是先将矩阵以每列拼接成一个行向量,而后,进行行向量切片操作。
主要操作如代码所示:

>> A = [1 2 3; 4 5 6; 7 8 9] %矩阵的声明,封号(;)表示本行的截止 
A =
     1     2     3
     4     5     6
     7     8     9
>> A(2, 1) %提取第2行第1列的元素
ans =
     4
>> cV2 = A(:, 2) %获取矩阵A的第2列元素,获取行类似rV2 = A(2, :)
cV2 =
     2
     5
     8
>> A(end, end) %内置end的使用
ans =
     9
>> A([1 3], [2 3]) %以向量作为索引
ans =
     2     3
     8     9     
>> D = logical([1 0 0; 0 0 1; 0 0 0]) %以逻辑矩阵作为索引,找出非零元素对应元素的位置
D =
     1     0     0
     0     0     1
     0     0     0
>> A(D)
ans =
     1
     6
 >> A(:) %矩阵的冒号(:)运算
ans =
     1
     4
     7
     2
     5
     8
     3
     6
     9
>> A(2:5) 
ans =
     4     7     2     5
>> 

1.8.3选择矩阵维数

任意的Matlab任何变量A(标量、向量、矩阵、多维数组等)都表示为数组。
ndims(A):返回数组A的维数(值必大于等于2,标量也是1x1的数组)。
size(A, dim):返回数组A第dim个维度的大小。当dim大于实际维数时,返回1。

>> A = [1 2 3; 4 5 6; 7 8 9] %矩阵的声明,
A =
     1     2     3
     4     5     6
     7     8     9
>> ndims(A) %获取矩阵A的维
ans =
     2
>> size(A, 1) %获取矩阵A的第一维大小(行数)
ans =
     3

1.9常用的数组生成函数

以下列出7种常用数组生成函数(更便于模拟数字图像,验证数字图像处理算法等)。
zeros(M, N):生成一个大小为M x N的double类矩阵,元素均为0。

注意:zeros(M) 等效于zeros(M, M), 生成一个大小为M x M的方阵。如下函数类似。

ones(M, N):生成一个大小为M x N的double类矩阵,元素均为1。
true(M, N):生成一个大小为M x N的logical类矩阵,元素均为1。
false(M, N):生成一个大小为M x N的logical类矩阵,元素均为0。
magic(M):生成一个大小为M x M的“魔术方阵”,其中每行、每列和主对角线中的元素之和均相等,且元素均为整数。
rand(M, N):生成一个大小为M x N的矩阵,每个元素都是在区间[0,1]中均匀分布的随机数。
randn(M, N):生成一个大小为M x N的矩阵,其元素是正态分布的随机数,均值为0,方差为1。

>> 5*ones(3) %等效于5*ones(3, 3)
ans =
     5     5     5
     5     5     5
     5     5     5
>> rand(2, 3)
ans =
    0.7922    0.6557    0.8491
    0.9595    0.0357    0.9340
>> randn(2)
ans =
    0.4889    0.7269
    1.0347   -0.3034
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值