1.1 MATLABによる画像処理の基本

# 目次へのリンク
[MATLABによる画像処理・コンピュータービジョン入門目次](https://qiita.com/tohruk/items/e5f7939b622bcf2e3c4c)

# 概要


MATLABによる画像の取扱いを見ていきます。画像は行列操作とみなせますのでMATLABが得意な領域です。

対応ファイル：[I1_01_commandline.m](https://github.com/mathworks/MATLAB-IPCV-Eval-Kit-JP/blob/master/demo_files/I1_01_commandline.m)


# 四則演算、代入、セミコロン


MATLABはインタプリタ型の言語ですので、コマンドウィンドウでリターンキーを押すことで結果をすぐに見ることができます。


```matlab:MATLABコード
2+3
```
```text:実行結果
ans = 5
```

変数定義不要です。


```matlab:MATLABコード
a=2+3
```
```text:実行結果
a = 5
```


セミコロンを付けると結果を表示しません。


```matlab:MATLABコード
a=2+3;
```
# 行列操作による画像の取扱い


ここでは、`magic`という関数を用い、１から25の数を一回ずつ使い、縦・横・斜めどこを足し合わせても、同じ数になる、魔方陣という行列を生成してみます。


```matlab:MATLABコード
>> magic(5)      % 先ず、5行5列の行列を生成します。
```
```text:実行結果
ans = 5x5    
    17    24     1     8    15
    23     5     7    14    16
     4     6    13    20    22
    10    12    19    21     3
    11    18    25     2     9

```
## 行列を変数Aに代入


MATLABは変数の定義が必要ありませんので、このように、変数Aに代入することで変数が自動的に作成されます。


```matlab:MATLABコード
A=magic(5) 
```
```text:実行結果
A = 5x5    
    17    24     1     8    15
    23     5     7    14    16
     4     6    13    20    22
    10    12    19    21     3
    11    18    25     2     9

```
## 行列を画像として表示


MATLABには、可視化用の様々な関数が用意されています。 ここでは`imshow`という関数を用いて表示したいと思います。 1が真っ黒・最大値の25が真っ白として表示します。


```matlab:MATLABコード
imshow(A, [],'InitialMagnification','fit');
```

![figure_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14336/9e949e68-5a6c-ee1e-2e6b-2aae68363cad.png)


このように画像が表示されますが、行列のそれぞれの要素の値が、各Pixelの明るさに対応していて、2次元行列と画像が１：１に対応していることが分かります。


## 10以下のものを除去し、10より大きなものは残す


 MATLABでは行列のまま取り扱えますので、簡潔な記述で処理をすることができます。MATLABでは、行列に対する様々な便利な演算子が用意されており、例えば、行列の各要素と、数値10を比較したいときには、比較演算子が使えます。


```matlab:MATLABコード
B=A<10
```
```text:実行結果
B = 5x5 の logical 配列    
   0   0   1   1   0
   0   1   1   0   0
   1   1   0   0   0
   0   0   0   0   1
   0   0   0   1   1

```


 このように、行列と数字10を比べてやることで、10よりも小さい要素位置には１、10以上のところは0になった行列を得ることができます。


# MATLABでは小かっこで要素を指定


例えば、行列のAの第1行・1列目を指定するには小かっこを用います。


```matlab:MATLABコード
A(1,1)
```
```text:実行結果
ans = 17
```
## 要素の指定には行列を使うことも可能


要素指定部分に、B行列をつかうとB行列の1のところの要素のみ取り出すことができます。


```matlab:MATLABコード
A(B)    
```
```text:実行結果
ans = 9x1    
     4
     5
     6
     1
     7
     8
     2
     3
     9

```
## B行列の1の要素に対してのみ処理を実行


要素指定部分にB行列を使い、代入を行うことも可能です。


```matlab:MATLABコード
A(B)=1
```
```text:実行結果
A = 5x5    
    17    24     1     1    15
    23     1     1    14    16
     1     1    13    20    22
    10    12    19    21     1
    11    18    25     1     1

```
## 可視化して確認


画像解析の機能が豊富な、`imtool`という別のツールを使ってみます。


```matlab
imtool(A, []);
```

![figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14336/a0a4ca8b-7d14-a602-a570-f8f8a5218983.png)

灰色部分が値1になり真っ黒になっていることが分かります。右下に、マウスの座標やその位置の値が表示されます。定規アイコンで距離を測ることもできますし、イメージ の下の ピクセル領域 というメニューを使うと、このように各Pixelの明るさの値を表示することもできます。カラーの場合は、3つの値が表示されます


## 行列をスカラーと同様に扱える

```matlab:MATLABコード
A+10
```
```text:実行結果
ans = 5x5    
    27    34    11    11    25
    33    11    11    24    26
    11    11    23    30    32
    20    22    29    31    11
    21    28    35    11    11

```
```matlab:MATLABコード
sin(A)
```
```text:実行結果
ans = 5x5    
   -0.9614   -0.9056    0.8415    0.8415    0.6503
   -0.8462    0.8415    0.8415    0.9906   -0.2879
    0.8415    0.8415    0.4202    0.9129   -0.0089
   -0.5440   -0.5366    0.1499    0.8367    0.8415
   -1.0000   -0.7510   -0.1324    0.8415    0.8415

```
## 飽和処理も自動で行ってくれる


符号なし8bit整数型(`uint8`)はデフォルトで飽和処理が有効になっています。意図しないオーバーフローを防いでくれます。


```matlab:MATLABコード
a = uint8(255)
```
```text:実行結果
a = 255
```
```matlab:MATLABコード
a + 1
```
```text:実行結果
ans = 255
```
# 論理インデックスの活用


A行列と10を比べて作ったB行列を画像として表示してみます。


```matlab:MATLABコード
B
```
```text:実行結果
B = 5x5 の logical 配列    
   0   0   1   1   0
   0   1   1   0   0
   1   1   0   0   0
   0   0   0   0   1
   0   0   0   1   1

```
```matlab:MATLABコード
imshow(B,[],'InitialMagnification','fit');
```

![figure_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14336/5d30667a-86ee-d603-789e-cfaae25c2fed.png)



10よりも小さい要素は白、10より大きい要素は黒の二値画像になっていて、大小比較演算だけで2値画像が作れることが分かります。その他にも、例えば、ある行列の一部を0にしたい場合は下記のように~(論理否定)が使えます。


```matlab:MATLABコード
B                % このようなB行列の1のところを、先ほどのように1にするのではなく0にしたい場合
```
```text:実行結果
B = 5x5 の logical 配列    
   0   0   1   1   0
   0   1   1   0   0
   1   1   0   0   0
   0   0   0   0   1
   0   0   0   1   1

```
```matlab:MATLABコード
~B               % チルダで、行列の0, 1を反転
```
```text:実行結果
ans = 5x5 の logical 配列    
   1   1   0   0   1
   1   0   0   1   1
   0   0   1   1   1
   1   1   1   1   0
   1   1   1   0   0

```
```matlab:MATLABコード
A                % A行列を確認
```
```text:実行結果
A = 5x5    
    17    24     1     1    15
    23     1     1    14    16
     1     1    13    20    22
    10    12    19    21     1
    11    18    25     1     1

```
```matlab:MATLABコード
A .* ~B          % チルダB の各行列の要素同士の掛け算 (*の前に.を置くことで出来ます)
```
```text:実行結果
ans = 5x5    
    17    24     0     0    15
    23     0     0    14    16
     0     0    13    20    22
    10    12    19    21     0
    11    18    25     0     0

```
# 目次へのリンク

[MATLABによる画像処理・コンピュータービジョン入門目次](https://qiita.com/tohruk/items/e5f7939b622bcf2e3c4c)

# 参考

   -  [配列インデックス付け](https://jp.mathworks.com/help/matlab/math/array-indexing.html) 

# 謝辞

本記事は@eigsさんの[livescript2markdown](https://github.com/minoue-xx/livescript2markdown)を使わせていただいてます。