第4回 MATLAB seminar 2021年07月01日
最終更新:2020/07/01
畳み込み ( convolution ) の直感的な説明を行い, 画像のぼかしなどのフィルタが畳み込みで実現できることを実践した. また, いくつかの行列の可視化を行った.
移動平均
移動平均は最も簡単な畳み込みの例であろう. MATLABに入っているsunspotデータに適用してみる
load sunspot.dat % サンプルデータをよみこむ d = sunspot(:, 2); % ほしいデータだけとってくる plot(d) % 可視化
長さ7の移動平均を, 畳み込みによって得てみる.
h = [1 1 1 1 1 1 1]/7; % フィルターを作る dd = conv(d, h); % 元データにフィルタを畳み込む plot(d); hold on % 元データを表示 plot(dd) % 重ねて表示
もちろん, こんな方法とらなくてもMATLABには移動平均を計算する函数 ( movmean ) がある.
画像を扱う
画像を読み込む
jpegやpngをよむときはimread
を使うと便利である.
可視化にはimshow
が便利である.
読んだ写真のサイズは今回, 667×1000×3になっている.
これは, 縦ピクセル数×横ピクセル数×RGBである.
また, データ型はuint8
( 8 ビット符号なし整数配列 ) となっている.
これは, RGBそれぞれが0-255の値をとるからである.
double(img)
で実数に変換できるが, 無駄にメモリを食うだけである ( 必要なときもある ) .
% 画像を読み込む, 表示 img = imread('top1.jpg'); % 表示し, RGB各成分をみてみる. subplot(221) imshow(img) title("元画像 ( カラー ) ") subplot(222) imshow(img(:, :, 1)) title("R成分") subplot(223) imshow(img(:, :, 2)) title("G成分") subplot(224) imshow(img(:, :, 3)) title("B成分")
RGB各成分は白いほど値 ( 輝度 ) が大きいことを意味する. 空の白い部分は, RGBすべての成分が大きいが, 青が濃い部分は赤色の成分が小さいとわかる.
imshow以外で可視化する.
imshow
はRGBを考慮した表示をしてくれるので, いかにも写真として見えるが, 本質的にはただの数字の並びである.
ここでは, 一般的に行列を可視化するツールを用いて可視化してみる. その前に, img = rgb2gray(img)
でグレースケール化しておく.
まず, imagesc
を使う.
これは, どんな行列でも適当にスケーリングしてイメージとして表示してくれる.
imagesc(img) colorbar % 横のスケール ( カラーバー ) を表示. 値が大きいほど輝度が大きい ( 白っぽい ) . colormap hot % カラーマップをhotに変更. 色々用意されているので試すと良い.
写真として表示してくれているわけではないので, もはや縦横比は崩れている. カラーマップの一覧はコチラ. 色々かえると楽しい. 自分で作ることもできる.
次はmesh(img)
を使ってみる.
これは, 輝度を高さで, つまり立体的に示してくれる.
フィルターや何かの閾値を決める時案外便利だったりする.
他にも色々は表示法がある. 基本的に写真には向いていないものが多いので紹介しないが, どうなるかくらい見てみるといいと思う.
フィルターをかける
MATLABで ( 畳み込みで表現できる ) フィルタを作るのは簡単である.
- フィルタを作る
conv2
で畳み込む
- フィルタ
h
を作る (fspecial
函数に有名所はそろっている ) img2 = imfilter(img, h)
でフィルタをかける
- 平均フィルタ:各要素の周辺の平均値を計算する. つまり, 画像がぼやける. 移動平均の2次元版である.
- ラプラシアンフィルタ:各要素の周辺の差分をとるイメージである. 微分に似ていて, エッジが強調される.
- トップハットフィルタ:元画像を強くぼやかした画像を, 元画像から減算するイメージ. 照度が均一化される.
% 1. gaussian h = fspecial('average', 30); img1 = imfilter(img, h); % 2. laplacian h = fspecial('laplacian', 0.1); img2 = imfilter(img, h); % 3. tophat se = strel('disk', 12); % 円形のフィルタのようなものを作成 img3 = imtophat(img, se); imshow(imadjust(img3)) % かなり暗い画像になっているので, imadjust函数でコントラストを上げている.
平均値フィルタ.
ラプラシアンフィルタ.
トップハットフィルタ.