积累科研中常用的MATLAB技巧(精品)

1. matlab文件批量处理

在使用MATLAB的过程中,我们经常需要批量处理文件,本小节主要介绍了批量处理文件的一些常用操作。

解决的问题:在一个文件夹下的有多张名称没有规律图片,如何使用matlab程序自动提取文件名,并遍历每张图片?我们可能面临的情况如下:
在这里插入图片描述
针对上面的问题,我们获取批量文件名的主要流程为:
① 指定需要批量处理的文件夹路径path;
② 指定文件后缀(如“.jpg”,“.txt”,“.dat”等等),若不指定则全类型读取(解决case2);
③ 从结构体中获取文件名元胞数组,文件名保存在元胞中。

具体matlab代码如下,前三行分别对应三个流程,后半部是遍历文件的示例:

% 文件名的批量读取
path = './示范读取批量文件/';    % 指明哪个文件夹
file_set = dir(fullfile(path,'*.jpg'));	% 读取后缀为.jpg的文件信息,保存为结构体数组
name_set = {
    
    file_set.name};             % 获取批量的文件名,保存为元胞数组

获取文件名集合后,对其进行遍历操作:

% 文件名批量获取已完成,下面是遍历使用文件的示例
for i = 1:length(name_set)
    filename = [path,name_set{
    
    i}];  % 注意组合“文件夹+文件名”才可读取到图片
    img = imread(filename);         % 执行后续操作
    imshow(img);
    pause(0.5);     % 暂停0.5s,把图片显示出来
end

其中dir函数就是批量获取文件名称的函数;fullfile函数是将文件夹路径与文件名后缀组合成新的文件路径;“*”星号表示通配符,dir函数可以获取任意字符串占用星号位置的文件名。我们也可以通过把后缀改为“ABC*DEF.jpg”的形式进一步限定只获取“ABC*DEF.jpg”格式的文件名。

2. matlab图形窗口设置

2.1 设置窗口位置及大小

在使用MATLAB绘图的过程中,往往MATLAB直接弹出来的窗口位置和大小不是我们想要的,所以这时候我们可以在程序中添加set命令进行调整。设置方法如下:

img = ones(512);
figure(1),imshow(img);
set(gcf,'Units','Pixel','position',[200, 200, 600, 600]);

其中gcf表示获取和指定图形窗口的坐标参数。

运行之后结果如下:
图形窗口显示设置
另外我们也可以通过占比来设置图窗位置和大小:

img = ones(512);
figure(1),imshow(img);
set(gcf,'Units','normalized','position',[0.2, 0.2, 0.5, 0.5]);

注意这里的占比是用显示器的分辨率进行计算的。其运行结果如下
在这里插入图片描述

2.2 设置窗口内图像的大小和位置

上面一部分是介绍如何调整figure的大小和位置,下面介绍如何设置figure中的图像大小和位置。

img = zeros(512);
imshow(img);
set(gca,'Units','normalized','position',[0.1 0.1 0.4 0.4]);

结果:
在这里插入图片描述
同样地,如果需要调整subplot中每个子图的大小和位置,也可以使用改命令进行调整,不过每个子图的具体位置参数可能需要自己手动计算一下。

2.3 设置窗口内图片以不同格式显示

当我们用matlab绘制出不同的图片的时候,我们可能需要图片以不同的格式进行显示,具体实现方法如下:

figure,
ax1 = subplot(221);	% 将subplot复制给一个变量
colormap(ax1 ,gray)	% 对该变量进行颜色设置

完整代码和下一节的保存一起展示,不同显示格式的运行结果如下:
在这里插入图片描述

2.4 将figure窗口保存为图片

在matlab中,我们常常创建一个figure之后再显示图片,比如我们把多幅对比图放置在一个figure窗口中对比等等,那么当我们想要保存这样的figure为图片的时候我们可以进行如下操作:

% 流程:创建四幅图 -> 放置在子图中以不同的方式进行显示 -> 保存当前figure窗口为图片

clc, clear
close all

% 创建cameraman图片
img = imread('cameraman.tif');

% 不同显示格式
figure,
ax1 = subplot(221); imshow(img), title('gray显示格式', 'Fontsize',20);
colormap(ax1 ,gray),colorbar;
ax2 = subplot(222); imshow(img), title('hot显示格式', 'Fontsize',20);
colormap(ax2 ,hot),colorbar;
ax3 = subplot(223); imshow(img), title('jet显示格式', 'Fontsize',20);
colormap(ax3 ,jet),colorbar;
ax4 = subplot(224); imshow(img), title('copper显示格式', 'Fontsize',20);
colormap(ax4 ,copper),colorbar;

% 保存figure为图片
set(gcf,'position',[500, 100, 1000, 800]);  % 设置figure位置和大小
tmp_img = frame2im(getframe(gcf));      % 将figure转化为图片再保存
imwrite(tmp_img,'./figure1.jpg');

最终将第3小节的结果保存到当前文件夹下:
在这里插入图片描述

3. matlab并行处理

parfor中的使用添加详细说明:
https://ww2.mathworks.cn/help/parallel-computing/parfor.html?searchHighlight=parfor&s_tid=srchtitle

开启多核运算的方法:

core_number=12;            %想要调用的处理器个数
parpool('local',core_number);

使用方式:

parfor i = 1:N
		x(i)  = i;
end

4. MATLAB图像处理(★★★)

4.1 整理图像处理中经常用到的函数

功能 命令
图像尺寸变换 Image = imresize(Image,[512,512]);
复制数组(行m次,列n次) B = repmat(A, m, n) ;
计算数组的元素个数 num = numel(A) ;|
计算向量的元素乘积 B = prod(A);
归一化函(0,1之间) f = @(x) (x-min(x(: )))./(max(x(: ))-min(x(: )));

4.2 给图像周边补零、复制和镜像填充;

关于padarray的matlab文档注解:
https://ww2.mathworks.cn/help/images/ref/padarray.html?searchHighlight=padarray&s_tid=srchtitle
B = padarray(A, [3 4]); % 默认补零填充,行和列各自两个方向都进行填充;
B = padarray(A, [3 4],1); % 用1进行填充

4.3 如何分立地索引图像(数组、彩图)中的某些像素

  问题描述:在对图像进行索引时,我们经常需要只索引某些分立的点。比如下图,我对camerman的图片使用find(img==167)之后,返回图像中像素值等于167的坐标,也这些坐标是分立,如何使用这些分立的坐标对图像进行索引?
在这里插入图片描述
解决思路:实现数组的分立索引主要通过顺序索引来实现,而不是坐标索引;对于彩色图像,只要在顺序索引上添加n倍 “长*宽”,就可以实现三个通道的索引,具体代码可参考如下:

clc, clear
close all

img = imread('cameraman.tif');	
index = find(img==167);	% 获取数组顺序索引,可直接分立索引数组
% [x, y] = find(img==167); % 获取数组x,y坐标索引,需转为顺序索引才能分立索引,不然会索引整行整列重叠区域;

img_color = repmat(img, 1, 1, 3);	% 灰度图像转为三维彩色图像,可以在后续处理中显示颜色
[l,w,~] = size(img_color);		% 获取图像的长和宽
mask = img_color;	% 复制图像,对mask进行处理
mask(index) = 255;	% 红色的强度值是[255 0 0],所以把对于坐标的强度值进行更换即可
mask(index+l*w) = 0;
mask(index+2*l*w) = 0;
figure, imshow([img_color, mask]);

如果采用x,y坐标索引,则不能正确分立地处理图像,其结果如下:
在这里插入图片描述

4.4 如何获取图像中任意四边的mask

  问题描述:按顺时针从左上角开始获取四个顶点的坐标,如何提取由四个顶点所确定的任意四边形区域。
在这里插入图片描述
解决思路:计算出四条直线的表达式,再根据每条边的取向约束出我们的四边形。
原理:由两点式的直线表达式可知  y = x 2 − x 1 y 2 − y 1 ( x − x 1 ) + y 1 y = \frac{ { {x_2} - {x_1}}}{ { {y_2} - {y_1}}}(x - {x_1}) + {y_1} y=y2y1x2x1(xx1)+y1,对于(m,n)点来说,如果 n>y(m) , 则说明该点高于直线,即当满足 n − x 2 − x 1 y 2 − y 1 ( m − x 1 ) − y 1 > 0 n- \frac{ { {x_2} - {x_1}}}{ { {y_2} - {y_1}}}(m - {x_1}) - {y_1}>0 ny2y1x2x1(mx1)y1>0可以选择出高于该直线的区域,同理,只要把满足四边形区域的四个约束都表示出来,即可通过并集获得四边形区域。具体实现方式如下:

% 实现图像中任意四边形的提取

clc, clear
close all

% 初始化
img = imread('cameraman.tif');	
[x_p,y_p,~] = size(img);        % 获取图像尺寸
[m,n] = meshgrid(1:y_p,1:x_p);  % 创建图像像素坐标

figure(1), imshow(img);
set(gcf, 'outerposition', get(0,'ScreenSize')); % 全屏显示

% 四边形内部的约束条件
[x,y] = ginput(4);      % 利用鼠标获取四个顶点数据
condition1 = n-(y(2)-y(1))/(x(2)-x(1))*(m-x(1))-y(1) > 0;
condition2 = m-(x(3)-x(2))/(y(3)-y(2))*(n-y(2))-x(2) < 0;
condition3 = n-(y(4)-y(3))/(x(4)-x(3))*(m-x(3))-y(3) < 0;
condition4 = m-(x(1)-x(4))/(y(1)-y(4))*(n-y(4))-x(4) > 0;
% figure, imshow([condition1 condition2;condition3 condition4])
index = condition1 & condition2 & condition3 & condition4;
figure(2), imshow(index);

% 求解
mask = zeros(size(img));
mask(index) = img(index);
figure(3),imshow([img mask]);

可提取任意四边形区域:
在这里插入图片描述

5 其他tips

1.判断某个文件路径是否存在

exist('filepath','file');	% 判断某个文件是否存在
exist('path','dir');		% 判断某个路径是否存在

2.判断变量A是否属于某一数据类型

isa(A, 'uint16')	

3.将数据保存到excel中

xlswrite('./H的对比.xlsx',H,'Sheet1',['E1']);	

Guess you like

Origin blog.csdn.net/qq_34917728/article/details/113774778