LoginSignup
23
14

More than 3 years have passed since last update.

【MATLAB】指定フォルダ内のファイルを検索して処理をする

Last updated at Posted at 2020-03-26

はじめに

何らかの処理をすべきファイルが大量にあって,一つ一つ手作業で処理をするのは大変である.
指定したフォルダ内の指定した拡張子のファイルを一括で処理したい.

今回はサンプルとして,
指定したフォルダとそのサブフォルダ内の全てのWAVファイルを検索し,一つ一つのファイルを開いて,時間波形を描いてPNGで保存する
という処理をMATLABで作っていく.

その他細かい話として,
PNGの保存先は元のWAVと同じとし,ファイル名は「元のWAVファイル名.png」とする
処理中はプロセスバーを表示する
とする.

ファイルを検索する


rootDir = uigetdir(pwd, '分析するディレクトリを指定してください');
if(rootDir==0)
    disp('処理を終了します');
    return
end

% カレントディレクトリをバッファ
origDir = pwd;

% カレントディレクトリを変更
cd(rootDir);

% カレントディレクトリとサブディレクトリを検索
fileList = dir('**/*.WAV');

% カレントディレクトリを戻す
cd(origDir);

フォルダ選択ダイアログ

rootDir = uigetdir(pwd, '分析するディレクトリを指定してください');

でフォルダ選択ダイアログが出てきて,rootDirに指定したフォルダのフルパスが入る.
なお,ダイアログをキャンセルで閉じた場合はrootDirには0が入る.

dialog.png

ファイルリストの取得

fileList = dir('**/*.WAV'); % で指定したフォルダとサブフォルダを検索
% もしくは
fileList = dir('*.WAV'); % と打つと指定したフォルダだけを検索する

fileListは以下のようなフィールドなどが入っている構造体である.

フィールド名 説明
name ファイル名またはフォルダ名
folder ファイルまたはフォルダのフルパス

構造体の詳細は フォルダーの内容の一覧表示 -MATLAB dir- MathWorks を参照.

ファイルを一つ一つ処理する


% 1つ1つファイルを処理していく
for n = 1:length(fileList)
    % ファイルのフルパスを取得
    fullpath = fullfile(fileList(n).folder, fileList(n).name);
    % メインの処理
    sampleSaveGraph(fullpath);
end

ファイルのフルパスの取得

fullpath = fullfile('C:\aaa\bbb', 'ccc.txt')

と打つと,fullpath'C:\aaa\bbb\ccc.txt'が入る.

fullpath = ['C:\aaa\bbb' '\' 'ccc.txt'];

でもいいと思うけど,Linuxだとファイル区切り文字が'/'になるので,fullfileを使ったほうがマルチプラットフォームに対応していて捗るらしい.

メインの処理

sampleSaveGraphは自作の関数で,引数にWAVファイルのフルパスを入れると時間波形を作成してグラフを保存してくれる.
実装は↓みたいな感じ.

sampleSaveGraph.m
function sampleSaveGraph(fullpath)
% WAVを開く
[y, Fs] = audioread(fullpath);

% グラフを描く
N = length(y);
t = ((1:N)-1)/Fs;
h = figure('WindowState','minimized');
plot(t, y);
xlim([0, t(end)]);
ylim([-1, 1]);
[filepath ,name, ext] = fileparts(fullpath);

% グラフタイトルはWAVファイル名とする
title([name, ext],'Interpreter','none');

xlabel('時間[秒]');
ylabel('振幅');

% 保存するファイルのフルパスを生成
filename = fullfile(filepath,[name, '.png']);
% ファイルを保存
saveas(h, filename);

close(h);
end

chirp_10-100Hz_0_8_5s.png
上記のような画像が保存される.

Figureを最小化状態で立ち上げ

h = figure('WindowState','minimized');

とすると,最小化した状態のFigureウィンドウを立ち上げてくれるらしい.
そのまま立ち上げちゃうとプロセスバーが隠れて見えなくなっちゃうので,最小化で処置をした.

ファイル名をグラフのタイトルにつける

[filepath ,name, ext] = fileparts(fullpath);
title([name, ext],'Interpreter','none');

でファイル名をタイトル表示する.
'Interpreter'オプション無しの場合
titleにInterpreterオプションをつけないと,ファイル名にアンダースコアがあった場合に下付き文字と判定されて上記画像のように表示されるので注意.

プロセスバーを表示

% プロセスバーを立ち上げる
h = waitbar(0, waitBarText(0, length(fileList)));

% 1つ1つファイルを処理していく
for n = 1:length(fileList)

    % メインの処理

    % プロセスバーを更新
    waitbar(n/length(fileList), h, waitBarText(n, length(fileList)));
end
% プロセスバーを閉じる
close(h);

function s = waitBarText(n, total)
s = sprintf('Please wait...[%d/%d]', n, total);
end

waitbarの第一引数には0~1の実数が入る.
waitbar.png
上記のようなプロセスバーが出てくる.

処理全体

sample_search_files_script.m

clc
clear all
close all

rootDir = uigetdir(pwd, '分析するディレクトリを指定してください');
if(rootDir==0)
    disp('処理を終了します');
    return
end

% カレントディレクトリをバッファ
origDir = pwd;
% カレントディレクトリを変更
cd(rootDir);
% カレントディレクトリとサブディレクトリを検索
fileList = dir('**/*.WAV');
% カレントディレクトリを戻す
cd(origDir);

% プロセスバーを表示
h = waitbar(0, waitBarText(0, length(fileList)));

% 1つ1つファイルを処理していく
for n = 1:length(fileList)
    % ファイルのフルパスを取得
    fullpath = fullfile(fileList(n).folder, fileList(n).name);
    % メインの処理
    sampleSaveGraph(fullpath);
    % プロセスバーを更新
    waitbar(n/length(fileList), h, waitBarText(n, length(fileList)));
end

close(h);
disp('処理が完了しました.');

function s = waitBarText(n, total)
s = sprintf('Please wait...[%d/%d]', n, total);
end

実行結果

実行前

folder01.png
試しにWAVファイルを4個用意した.(内1個は新しいフォルダー内に保存)

実行後

folder02.png
期待通りに,画像が保存された.

23
14
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
14