MATLABで迷路画像をパースする

こんにちは.けりです.

今回は,マイクロマウス公式から配布される迷路画像を,プログラムなどで読める形式に変換するMATLABコードを紹介します.

自分向けに作ったものなので,あまり高機能ではありませんが,参考になれば幸いです.

MATLAB コードの紹介

以下のMATLABコードを実行すると,画像を選択するポップが現れます.

迷路画像を選択すると,区画数などの解析結果が表示されるので,もしミスがあれば,ノイズの除去と壁の膨張というセクションのパラメータをいじって調整します.

mazeloader.m

ダウンロードはこちら

%% 入力
[filename, pathname] = uigetfile({'*.jpg;*.png;*.gif'}, 'Select the Maze Imgae');

%% 二値化&色反転(壁を1にするため)
original = imread([pathname, filename]);
bw = imbinarize(rgb2gray(original));
bw = imcomplement(bw);
imshow(bw);

%% 迷路の輪郭を抽出
colsum = sum(bw);
rowsum = sum(bw, 2);
[wM, we] = max(colsum(1:end/2));
[eM, ee] = max(colsum(end/2:end));
[nM, ne] = max(rowsum(1:end/2));
[sM, se] = max(rowsum(end/2:end));
trim = bw(ne:(se+size(rowsum,1)/2), we:(ee+size(colsum,2)/2));
trim = imresize(trim, [1600 1600]);

%% ノイズの除去と壁の膨張
trim = imopen(trim, ones(5));   % 白点線を除去
trim = imdilate(trim, ones(5)); % 白線を太くする
imshow(trim);

%% 迷路サイズを検出
trimsum = sum(trim);
trimsum = trimsum < sum(trimsum) / length(trimsum);
maze_size = sum(([trimsum 0]-[0 trimsum])>0);
msgbox(sprintf('迷路サイズは %d です', maze_size)); % 迷路サイズの表示

%% 壁の抽出
segsize = size(trim)/maze_size;
vwall = trim(round(segsize(1)/2:segsize(1):end), round(1:segsize(2):end-segsize(2)/3));
hwall = trim(round(1:segsize(1):end-segsize(1)/3), round(segsize(2)/2:segsize(2):end));
vwall = [vwall, ones(maze_size, 1)];
hwall = [hwall; ones(1, maze_size)];

%% 壁の合成
wall =        1 * vwall(:, 2:end);      % 東 0 bit
wall = wall + 2 * hwall(1:end-1, :);    % 北 1 bit
wall = wall + 4 * vwall(:, 1:end-1);    % 西 2 bit
wall = wall + 8 * hwall(2:end, :);      % 南 3 bit

%% ファイルに保存
output = reshape(sprintf('%x',wall), maze_size, maze_size);
output = ['"'*ones(maze_size, 1) output '",'.*ones(maze_size,1)];
new_filename = sprintf('%s.txt', filename);
dlmwrite(new_filename, output, 'precision', '%c', 'delimiter', '');
lmwrite(new_filename, wall, 'precision', '%x', 'delimiter', '');

出力形式

3:2:1:0 bit がそれぞれ 南:西:北:東 の16進数表示です.

+ 1 +
2   0
+ 3 + 

例えば

+---+---+
| 6   3 |
+   +   +
| d | d |
+---+---+

という迷路ならば,

63
dd

とテキストファイルに出力されます.

これ以外の順番にするには,MATLABコードの最後の出力の数字をいじることで変えることができます.

まとめ

とりあえず使うことはできますが,もっと使いやすく改良したいところです.

ちなみに,このコードのアイディアは,元MiceのY.I.さんから聞いたものを参考にしました.

ありがとうございます.