LoginSignup
5
6

More than 5 years have passed since last update.

Matlabで時間軸方向に連続する動画データを可視化する際の問題点と解決法

Last updated at Posted at 2017-03-05

Matlabで時間軸方向に連続する動画データを可視化する。この際に必要になる動画の各フレームに対する処理と、動画データにカラーマップを適用する処理をまとめた。

ソースは以下で公開
gist

使ったもの

問題点

matlabのim2frameを用いると、イメージをムービーフレーム(構造体配列)に変換することができる。

f = im2frame(X);

ムービーフレームを作製しておくと動画の再生(movie)や書き込み(writeVideo)に使うことができる。

そこでim2frameを用いて、動画データ(m x n x c x t)をムービーフレームに変換したい。

しかしこの関数の引数X
1. インデックス付きイメージトゥルーカラー イメージだけしか許されていない(see also: イメージの種類)
2. ndims>3の動画データ(m x n x c x t)は許されていない
の2点の制約があるため動画データを直接変換することはできない。

解決法

動画データの種類によって変わる

動画データ(トゥルーカラー)からムービーフレームへの変換

動画データ(m x n x 3 x t)の各フレームがトゥルーカラー イメージの場合はそれぞれをim2frameに代入するだけでよい。
普通にfor文を用いて以下のように処理してもよいが、

%% Test RGB Data (with for loop)
NofFrame = 300;
MovieData = rand(64, 64, 3, NofFrame);
for fi = 1:NofFrame
  frame(fi) = im2frame(MovieData(:, :, :, fi));
end
movie(frame, 1, 30);

arrayfunでスライスするとスッキリとなる。

%% Test RGB Data
NofFrame = 300;
MovieData = rand(64, 64, 3, NofFrame);

frame = arrayfun(@(fi) im2frame(MovieData(:, :, :, fi)), 1:NofFrame);
movie(frame, 1, 30);

データはランダムなカラーノイズ

動画データ(インデックス付き)からムービーフレームへの変換

動画データ(m x n x 1 x t)のインデックスに対応するmapを添える。

%% Test Ind Data
NofFrame = 300;
NofScale = 256;
MovieData = randi(NofScale, 64, 64, 1, NofFrame);

frame = arrayfun(@(fi) im2frame(MovieData(:, :, :, fi), hot(NofScale)),  1:NofFrame);
movie(frame, 1, 30);

動画データ(未整形)からムービーフレームへの変換

動画データ(m x n x 1 x t)が未整形の場合はmat2gray, gray2ind を使って動画の各フレームをインデックス付きイメージに変換する。

%% Test Mat Data (convert to Ind Data)
NofFrame = 300;
NofScale = 256;
MovieData = rand(64, 64, 1, NofFrame);

% convert mat -> (gray) -> ind
MovieData = gray2ind(mat2gray(MovieData , [min(MovieData(:)), max(MovieData(:))]), NofScale);

frame = arrayfun(@(fi) im2frame(MovieData(:, :, :, fi), cool(NofScale)), 1:NofFrame);
movie(frame, 1, 30);

ind2rgbを用いると、インデックス付きイメージからトゥルーカラー イメージに変換できるが、この関数は画像(m x n)に対してのみしかうまく動作しない。(色チャネルを結合する際のインデックスの振り方のせい)
どうしてもトゥルーカラーの動画データがほしい場合は以下のようにrgbを分けて出力し、catで3次元目を結合する。

%% Test Mat Data (convert to RGB Data)
% ind2rgb function doesn't work for 3-or-more dimentional FrameData
NofFrame = 300;
NofScale = 256;
MovieData = rand(64, 64, 1, NofFrame);

% convert mat -> (gray) -> (ind) -> (r, g, b) -> rgb
[r, g, b] = ind2rgb(gray2ind(mat2gray(MovieData , [min(MovieData(:)), max(MovieData(:))]), NofScale), spring(NofScale);
MovieData = cat(3, r, g, b);

frame = arrayfun(@(fi) im2frame(MovieData(:, :, :, fi)), 1:NofFrame);
movie(frame, 1, 30);

まとめ

  • 動画データをムービーフレームに変換することができる。
  • arrayfunを用いることでfor文を書かずにデータをスライスできる。
  • mat2gray, gray2indを連続して使うことでデータを変換できる。

参考

im2frame | movie | writeVideo | arrayfun | mat2gray | gray2ind | ind2rgb

5
6
0

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
5
6