Bootstrap

一、Matlab图像处理入门

专栏文章目录

一、 Matlab图像处理入门


今日任务:

  1. 调用imread读入一张图片;观察workspace中,内存变量的dimension和数据类型;
  2. 调用imshow直接显示图像(同时显示R通道、B通道和G通道);
  3. 对图像的三个通道进行简单平均,得到单通道,并进行显示。
    3.1 方法1,逐像素完成,使用两层for循环;
    3.2 方法2,直接利用矩阵运算完成;
    3.3 测试两种方法的时间。将代码至于tic和toc之间即可1

一、千呼万唤始出来——主角介绍

1、初识数字图像处理

  顾名思义,所谓“数字图像处理”就是对数字图像的相关操作。(权威说法:数字图像处理是指借助于数字计算机来处理数字图像2)。图像是通过视觉传感器把我们的三维世界映射到二维空间的一种载体( p s : ps: ps:映射的过程大量信息会被丢失,所以基于图像输入的三维重建是病态的。相关问题后期我们慢慢讨论),一幅图像可被定义为一个二维函数 f ( x , y ) f(x,y) f(x,y),其中的 x x x y y y是空间坐标,一对 ( x , y ) (x,y) (x,y)上面对应的幅值 f f f叫做图像在这一点的强度灰度。当 x x x y y y f f f是有限的离散数值的时候,就称这幅图像为数字图像

2、初识MATLAB

  MATLAB:美国人开发的一个十分牛逼的数学软件,主要功能有画图、图形处理、信号分析、无线通信……应用领域十分广泛,除此之外MATLAB内部函数都是科研和工程计算中的最新研究成果,而且经过了各种优化和容错处理,所以十分高效(如果你写出了效率更高的代替函数,那请收下我的膝盖,绝对是大牛!!!)。而且在其中很多领域的应用都被做成了工具包,可视化成都极高,极大减少了科研周期。且其使用的语言简单易于快速上手。总而言之,是你学习、科研的一大利器!

二、言归正传——快速进入任务

1.软件安装

  由于是付费软件,所以基本正规安装渠道就是安装学校或者公司的官方正版软件(按需安装各种工具包,随用随安装),此处不再赘述。

2.开始coding

  首先,我们使用imread()函数读入目标图片,并使用imshow()函数显示目标图片。

% 读取原图并显示
Im = imread('1.jpg'); %读入图片(三通道RGB图像)
%subplot(4,4,1); %此处是为了后面显示方便,在一个页面中显示$4*4$张图
imshow(Im);
title('原图');

看一波效果:

  至此,我们完成了任务1的一半:调用imread读入一张图片 以及任务2: 调用imshow直接显示图像

a.插播一个小技巧

  MATLAB之所以广受大家喜爱,主要还在与其友好的让使用者自学的功能设定。看别人代码函数不知道怎么办?不要着急,默默选中该函数,就像下图一样选中 " i m r e a d " "imread" "imread",然后敲击键盘 F 1 F1 F1,查看帮助文档,快速掌握函数用法并且能够查看相关示例。所以MATLAB入门怎么办?看帮助文档!看帮助文档!!看帮助文档!!!
在这里插入图片描述
相同的办法,我们再查看 " i m s h o w " "imshow" "imshow"的帮助:
在这里插入图片描述
  接着我们进行下一步操作:观察workspace中,内存变量的dimension和数据类型
   w o r k s p a c e workspace workspace在这里。目标图像 A A A因为是彩色图像,具有 R R R G G G B B B三个通道,所以数据大小是“ 373 ∗ 346 ∗ 3 373*346*3 3733463”的三维矩阵。数据类型是可显示的“ u i n t 8 uint8 uint8”类型。

在这里插入图片描述
  点击 A A A之后就可以看到矩阵 A A A中的每个具体值。
在这里插入图片描述
  然后,我们继续完成任务三:对图像的三个通道进行简单平均,得到单通道,并进行显示。共使用两种方法。

方法1:直接利用矩阵运算完成:

%方法1:mean函数求平均
tic
%R通道
R2 = A(:,:,1);
av = mean(R2,'all');    %此处是将二维数组转换成了一维数组,随后求平均
%fprintf('%f\n',av);
[r,c] = size(R2);   %size分别获取矩阵的行、列数
for i = 1:r
    for j = 1:c
        R2(i,j) = av;
    end
end
subplot(4,4,10);
imshow(R2);
title('矩阵平均—R通道');

%G通道
G2 = A(:,:,2);  
av = mean(G2,'all');    %此处是将二维数组转换成了一维数组,随后求平均
[r,c] = size(G2);   %size分别获取矩阵的行、列数
for i = 1:r
    for j = 1:c
        G2(i,j) = av;
    end
end
subplot(4,4,11);
imshow(G2);
title('矩阵平均—G通道');

%B通道
B2 = A(:,:,3);  
av = mean(B2,'all');    %此处是将二维数组转换成了一维数组,随后求平均
[r,c] = size(B2);   %size分别获取矩阵的行、列数
for i = 1:r
    for j = 1:c
        B2(i,j) = av;
    end
end
subplot(4,4,12);
imshow(B2);
title('矩阵平均—B通道');
toc

方法2:逐像素完成,使用两层for循环:

%方法二:逐像素完成三通道取平均
tic
R3 = double(A(:,:,1));
R4 = A(:,:,1);
a=0;
for i = 1:r
    for j = 1:c
        a = a+R3(i,j)/r/c;
    end
end
%fprintf('%f\n',a);
for i = 1:r
    for j = 1:c
        R4(i,j) = a;
    end
end
subplot(4,4,14);
imshow(R4);
title('像素平均—R通道');

a = 0;
G3 = double(A(:,:,2));
G4 = A(:,:,2);
[r,c] = size(G3);
for i = 1:r
    for j = 1:c
        a = a+G3(i,j)/(r*c);
    end
end
%fprintf('%f\n',a);
for i = 1:r
    for j = 1:c
        G4(i,j) = a;
    end
end
subplot(4,4,15);
imshow(G4);
title('像素平均—G通道');

a = 0;
B3 = double(A(:,:,3));
B4 = A(:,:,3);
[r,c] = size(B3);
for i = 1:r
    for j = 1:c
        a = a+B3(i,j)/(r*c);
    end
end
%fprintf('%f\n',a);
for i = 1:r
    for j = 1:c
        B4(i,j) = a;
    end
end
subplot(4,4,16);
imshow(B4);
title('像素平均—B通道');
toc

上运行结果图:
在这里插入图片描述

  最后,按照任务要求,我们截取运行时间对比:

  显而易见,直接利用矩阵完成各通道取平均比逐像素操作快了不少。MATLAB内置函数的运行效率之高、优化程度之高可见一斑。

  至此,今日任务完成!


三、总结(划重点)

1、采用直接提取图像通道的方法,提取出的只是单通道分量,显示的图像为灰度图像:采用将所需通道保留,其余两通道置 0 0 0的方式则可得到三通道图像,此时图像为彩色图像;
2、直接读取的单通道( e g : R = A ( : , : , 1 ) eg:R = A(:,:,1) eg:R=A(:,:,1))数据类型为 u i n t 8 uint8 uint8,在进行累加时最大不能超过 255 255 255,所以使用遍历矩阵求平均时应当转换成 d o u b l e double double类型进行计算,但是在进行显示的时候会出问题,所以应当对uint8类型的矩阵进行平均值赋值。

Q:在使用mean进行矩阵求平均时不会出现类型不对的问题……

答:因为内置函数已经进行了相关容错处理。

链接: 完整源码


  1. I m a g e a n d V i d e o P r o c e s s i n g Image andVideo Processing ImageandVideoProcessing, Li Sun, School of Communication
    & Electronic Engineering, East China Normal University。 ↩︎

  2. 冈萨雷斯,数字图像处理(第三版)。 ↩︎

;