MATLABにおける画像処理の基本

この記事はMATLABで行う画像処理のやり方について説明する入門となります。

# はじめに

MATLABでは画像が配列として扱われるので、まず配列のことをよく理解しておいたら大分楽です。

配列に関する入門はこの前の記事で纏めていたので、まずはその記事を読むことをおすすめします。

https://qiita.com/phyblas/items/3a24b0e3745156a78d6b

画像処理に関する機能は一部特にパッケージを追加しなくてもすぐ使えますが、一部の関数は[Image Processing Toolbox](https://jp.mathworks.com/help/images/index.html)のものなのでインストールしておく必要があります。


# 画像を読み込む 〔[imread](https://jp.mathworks.com/help/matlab/ref/imread.html)〕

MATLABで画像データを扱う時に基本的に`imread`関数で画像ファイルを読み込んで、配列に変換します。色画像だったら「高さ×広さ×3」の3次元の配列に、無色画像だったら「高さ×広さ」の2次元の配列になります。値は0から255の8ビットの符号なし整数（uint8）。色の値はRGB（赤、緑、青）。

例としてこの記事の殆どの内容はこの画像を使うことにします。
<table><tr><td style="text-align: center"><font color="red"><code>sarada.jpg</code></font>

![sarada.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/b7d74349-0075-e18a-b59d-2b87db4dd8f6.jpeg)
（画像はアニメ「[変人のサラダボウル](https://ja.wikipedia.org/wiki/変人のサラダボウル)」2話から）
</td></tr></table>

画像を読み込んで調べてみます。
```matlab
ar_img = imread("sarada.jpg");
ar_size = size(ar_img)
ar_max = max(ar_img(:))
```
```:結果
ar_size =

   405   540     3


ar_max =

  uint8

   255
```

このように画像はMATLABの中での配列になって、これを使って色々やることができます。


# 画像の基本情報を取る 〔[imfinfo](https://jp.mathworks.com/help/matlab/ref/imfinfo.html)〕

画像ファイルに関する情報は`imfinfo`関数から取得できます。
```matlab
imginfo = imfinfo("sarada.jpg")
```
```:結果
           Filename: '/Users/phyblas/Documents/MATLAB/sarada.jpg'
        FileModDate: '20-Apr-2024 13:50:23'
           FileSize: 37195
             Format: 'jpg'
      FormatVersion: ''
              Width: 540
             Height: 405
           BitDepth: 24
          ColorType: 'truecolor'
    FormatSignature: ''
    NumberOfSamples: 3
       CodingMethod: 'Huffman'
      CodingProcess: 'Sequential'
            Comment: {}
```


# 画像を表示する 〔[imshow](https://jp.mathworks.com/help/matlab/ref/imshow.html)〕

MATLABの中で画像を表示するには普段`imshow`という関数を使います。使い方は色々ありますが、例えば直接画像ファイルの名前を入れたらその画像を読み込んで表示します。
```matlab
imshow("sarada.jpg")
```

![sarada_imshow.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/6d4b5046-58f4-aa92-6035-8f53b8b724ea.jpeg)

又は`imread`で3次元配列に読み込んでから使うのも同じ結果です。
```matlab
arimg = imread("sarada.jpg");
imshow(arimg)
```

無色の画像、つまり2次元配列も表示できます。例えばこの画像の赤の値だけ取って無色画像として表示します。
```matlab
arimg = imread("sarada.jpg");
imshow(arimg(:,:,1))
```

![sarada_imshow_r.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/a2b16f83-002b-6c37-1a1c-e684583bea36.jpeg)


# 画像をグラフとして表示する 〔[image](https://jp.mathworks.com/help/matlab/ref/image.html)〕

`imread`関数を使ったらグラフを書くみたいに画像を表示することもできます。この場合アスペクト比を変えたりグリッドを行けたりするもできて使い勝手がいいですね。
```matlab
figure(Position=[100 100 800 400])
image(imread("sarada.jpg"))
pbaspect([3 1 1])
grid
set(gca,GridLineStyle="--",LineWidth=2,GridColor="#660000")
```

![sarada_image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/6fe425c3-9beb-1c76-6c2e-fc70cd2a9b5c.jpeg)

グラフを書くことについては説明すると長くなるのでここでは割愛します。


# 画像を書き込む 〔[imwrite](https://jp.mathworks.com/help/matlab/ref/imwrite.html)〕

`imwrite`関数で配列を画像ファイルとして書き込むことができます。

例えば乱数で適当に作ってみた配列を画像として出力してみます。
```matlab
arimg = rand(200,400,3);
imwrite(arimg,"randimg.jpg")
```
![randimg.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/a58afc00-734b-a967-f29a-914ae8cf5efd.jpeg)

保存する配列はデータ型がdoubleでもuint8でもいいですが、doubleなら[0~1]で、uint8なら[0~255]範囲の値を使います。

２次元の配列の場合は無色の画像として保存されます。
```matlab
arimg = reshape(mod(1:40000,1250)/1250,200,200);
imwrite(arimg,"rangeimg.jpg")
```

![rangeimg.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/caa9f0e8-25ab-91b1-2009-bfcbdd99f773.jpeg)


# 配列としての機能を駆使する

画像はただの配列だから配列の基本がしっかりわかって使いこなせていれば特に関数を使わなくても色々できます。

例えば一部だけ切り取る。
```matlab
arimg = imread("sarada.jpg");
imwrite(arimg(140:240,180:270,:),"sarada_migime.jpg")
```

![sarada_migime.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/84ef4411-f2fd-7d7a-9b5e-21ea0f0f6f5c.jpeg)

明るいと暗いを逆にする。
```matlab
arimg = imread("sarada.jpg");
imwrite(255-arimg,"sarada_gyaku.jpg")
```

![sarada_gyaku.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/0d1feb2f-a07f-22bc-954d-63414c85b888.jpeg)

色んな数学計算をして各色の値を調整することもできます。ただし`imread`関数で読み込んだ配列はuint8なので、計算する時にまずデータ型をdoubleに変える必要があります。

例えば三角関数を使って波みたいな暗い縞を作ります。
```matlab
arimg = double(imread("sarada.jpg"));
arimg = arimg.*(0.8+cos(linspace(0,24*pi,540))*0.2);
arimg = arimg.*(0.8+cos(linspace(0,18*pi,405)')*0.2);
imwrite(uint8(arimg),"sarada_cos.jpg")
```

![sarada_cos.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/82145baf-708f-b479-0664-3a23621b405e.jpeg)


# 色を分ける 〔[imsplit](https://jp.mathworks.com/help/images/ref/imsplit.html)〕

色画像の配列はRGB3色から成されているから、どちらか使いたい時は`arimg(:,:,1)`、`arimg(:,:,2)`、`arimg(:,:,3)`のように書けばいいですね。

又は`imsplit`という関数を使って同時に3色を分けることもできます。

これを使って3色に分解して並んで表示してみます。
```matlab
arimg = imread("sarada.jpg");
[aka,midori,ao] = imsplit(arimg);
aka = aka.*reshape(uint8([1 0 0]),1,1,3);
midori = midori.*reshape(uint8([0 1 0]),1,1,3);
ao = ao.*reshape(uint8([0 0 1]),1,1,3);
imwrite([arimg aka;midori ao],"sarada_imsplit.jpg")
```

![sarada_imsplit.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/cce2e020-d04e-e428-3a78-bbc023525b18.jpeg)


# グレースケール 〔[im2gray](https://jp.mathworks.com/help/matlab/ref/im2gray.html)〕

`im2gray`で色画像を自然に無色（グレースケール）にすることができます。
```matlab
arimg = imread("sarada.jpg");
arimg_gs = im2gray(arimg);
imwrite(arimg_gs,"sarada_gs.jpg")
```

![sarada_gs.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/2eecc336-68b4-d444-b1d0-f0c78a17226e.jpeg)

この関数はただRGBの平均値を取るというわけではなく、「0.299 : 0.587 : 0.114」という違う重みで計算するのです。（[詳しくは公式サイト参考](https://jp.mathworks.com/help/matlab/ref/im2gray.html?s_tid=doc_ta)）

自分で計算してみてもやはり関数を使うのと同じ結果が出てきます。
```matlab
[aka,midori,ao] = imsplit(imread("sarada.jpg"));
arimg_gs = uint8(0.299.*aka + 0.587.*midori + 0.114.*ao);
imwrite(arimg_gs,"sarada_gs.jpg")
```

試しに単なる平均値を取ってみたら……。
```matlab
arimg = imread("sarada.jpg");
arimg_gs = uint8(mean(arimg,3));
imwrite(arimg_gs,"sarada_gs2.jpg")
```

![sarada_gs2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/54377e89-7e5f-0bf6-4954-db4ac1d50d27.jpeg)

本当に結果はちょっと違います。確かに`im2gray`を使った方が自然に感じますね。


# 画像をひっくり返す 〔[flip](https://jp.mathworks.com/help/matlab/ref/flip.html)〕

画像を縦方向をひっくり返すには`flip`関数を使うことができます。
```matlab
arimg = imread("sarada.jpg");
imwrite(flip(arimg),"sarada_flip.jpg")
```

![sarada_flip.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/85ef349f-1bf9-e1f3-8d77-5e3ad2a992ee.jpeg)

横の方向で逆にしたい場合は`2`を入れて軸を指定します。
```matlab
arimg = imread("sarada.jpg");
imwrite(flip(arimg,2),"sarada_flip2.jpg")
```

![sarada_flip2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/2b31fff9-d894-240e-920d-b1e503143755.jpeg)


# 画像のサイズ（解像度）を変える 〔[imresize](https://jp.mathworks.com/help/matlab/ref/imresize.html)〕

`imresize`関数によって画像を指定した`[高さ 広さ]`に大きくしたり小さくしたりできます。
```matlab
arimg = imread("sarada.jpg");
imwrite(imresize(arimg,[300 200]),"sarada_200x300.jpg")
```

![sarada_200x300.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/9d20fdd8-978b-c521-a761-b65e6a63d66f.jpeg)

もしただ高さだけ指定してアスペクト比を保つまま広さも変えたい場合は`NaN`と書くのです。
```matlab
arimg = imread("sarada.jpg");
imwrite(imresize(arimg,[300 NaN]),"sarada_300.jpg")
```

![sarada_300.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/3dd04173-64e4-41ee-2286-20c5c269b41f.jpeg)

広さだけ指定したい場合も同じ。

もし指定したのは一つの数値の場合それはピクセルではなく倍数を指定するということになります。

例えば半分サイズにします。
```matlab
arimg = imread("sarada.jpg");
imwrite(imresize(arimg,0.5),"sarada_x0.5.jpg")
```

![sarada_x0.5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/c1a06b7f-359f-c94b-3cd0-6c98a84b9014.jpeg)

その他にサイズ変更する時の内挿のメソッドも指定できます。既定は`bicubic`（双三次内挿）を使ってこれは一番自然にできますが、`bilinear`（双一次内挿）や`nearest`（最近傍内挿）にすることができます。

例えば左目のところだけ取って拡大してみて、`bicubic`と`nearest`の違いを見ます。
```matlab
arimg = imread("sarada.jpg");
arimg = arimg(171:230,301:380,:);
imwrite(imresize(arimg,4),"sarada_resize_bicubic.jpg")
imwrite(imresize(arimg,4,"nearest"),"sarada_resize_nearest.jpg")
```

![sarada_resize_bicubic.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/948e453e-2bd4-5df5-456e-cbc4c2be99d7.jpeg)
![sarada_resize_nearest.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/8dd3a75e-9a25-218c-6b5f-f24999939ef3.jpeg)

こうやって`nearest`を利用してモザイク処理もできます。
```matlab
arimg = imresize(imread("sarada.jpg"),0.1);
imwrite(imresize(arimg,10,"nearest"),"sarada_mozaiku.jpg")
```

![sarada_mozaiku.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/179ed513-b4a2-4c11-c721-bce632e89398.jpeg)


# 画像を回転させる 〔[imrotate](https://jp.mathworks.com/help/images/ref/imrotate.html)〕

`imrotate`関数で画像を好きな角度で回転させることができます。
```matlab
arimg = imread("sarada.jpg");
imwrite(imrotate(arimg,30),"sarada_rotate30.jpg")
```

![sarada_rotate30.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/383b6911-ad33-71a2-1774-c6f703228092.jpeg)

既定では回転した後何もないピクセルができてサイズが変わるが、同じ大きさのままにしたい場合は`"crop"`と書きます。
```matlab
arimg = imread("sarada.jpg");
imwrite(imrotate(arimg,45,"crop"),"sarada_rotate45.jpg")
```

![sarada_rotate45.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/1914b1f9-5980-e0a7-091a-7df10daa7f89.jpeg)


# 画像を繰り返して並べる 〔[repmat](https://jp.mathworks.com/help/matlab/ref/repmat.html)〕

`repmat`関数を使って同じ画像をコピーして何回も並べることができます。
```matlab
arimg = imread("sarada.jpg");
arimg = repmat(arimg,[5 4]);
imwrite(imresize(arimg,0.25),"sarada_repmat.jpg")
```

![sarada_repmat.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/db0766c0-104d-bfc2-39e6-0be126d17a1d.jpeg)


# パディングする 〔[padarray](https://jp.mathworks.com/help/images/ref/padarray.html)〕

`padarray`関数で周りの空なピクセルで埋めることができます。
```matlab
arimg = imread("sarada.jpg");
arimg = padarray(arimg,[15 50]);
imwrite(arimg,"sarada_padarray.jpg")
```

![sarada_padarray.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/50fb4765-675f-0e30-ef7f-6161677f6048.jpeg)

既定では`0`で埋められますが、`"replicate"`を書いたら境界のピクセルを取って繰り返すことになります。
```matlab
arimg = imresize(imread("sarada.jpg"),0.5);
arimg = padarray(arimg,[111 100],"replicate");
imwrite(arimg,"sarada_padarray_replicate.jpg")
```

![sarada_padarray_replicate.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/680c1ea5-c01a-82b8-e80b-59c097535f9a.jpeg)

`"circular"`にしたら画像を循環で繰り返します。`"symmetric"`は鏡の反射みたいに逆の方向で繰り返します。

その他にどの方向でパディングするか指定できます。既定では`"both"`つまり前も後ろも。前だけにしたいなら`"pre"`で、後ろなら`"post"`。これを`"circular"`、`"replicate"`、`"symmetric"`と共に書くこともできます。
```matlab
arimg = imresize(imread("sarada.jpg"),0.25);
arimg = padarray(arimg,[220 270],"symmetric","post");
imwrite(arimg,"sarada_padarray_symmetric.jpg")
```

![sarada_padarray_symmetric.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/f8ab1dd6-0148-3049-5ae5-51eee6d39e5f.jpeg)


# 色空間を変える 〔[rgb2hsv](https://jp.mathworks.com/help/matlab/ref/rgb2hsv.html)〕

普段色は<font color="red">R</font><font color="green">G</font><font color="#00f">B</font>3色の数値で表示されていますが、他の色空間を使う場合もあります。もう一つよく使われるのはHSV、つまり<ruby>色相<rt>しきそう</rt></ruby>（H）、彩度（S）、明度（V）です。詳しいことは割愛しますが、これが画像分析する時のこの空間を使う場合もあります。

`rgb2hsv`関数で普段のRGB空間からHSV空間に変えることができます。返される数値は0から1の小数の配列。

例えばHSVの値を分解してグラフで表示してみましょう。
```matlab
arimg = imread("sarada.jpg");
arimg_hsv = rgb2hsv(arimg);

figure(Name="HSV")
tiledlayout(2,2,Padding='none',TileSpacing='tight');

nexttile
imshow(arimg_hsv(:,:,1))
title("色相")

nexttile
imshow(arimg_hsv(:,:,2))
title("彩度")

nexttile
imshow(arimg_hsv(:,:,3))
title("明度")

nexttile
imshow(arimg)
title("元の画像")
```

![sarada_hsv.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/37709f8c-0380-13e3-5ce4-72a10724fbc4.jpeg)


# カラーマップを使う 〔[ind2rgb](https://jp.mathworks.com/help/matlab/ref/ind2rgb.html)〕

無色の画像を扱う時に単に黒から白で表示するよりもカラーマップを使って色にした方がいいかもしれません。

`ind2rgb`関数で無色画像からカラーマップで色に変換することができます。

グレースケールにされた画像に使って綺麗な色に変えてみます。
```matlab
arimg = imread("sarada.jpg");
arimg_gs = im2gray(arimg);
arimg_parula = ind2rgb(arimg_gs,parula);
imwrite(arimg_parula,"sarada_parula.jpg")
```

![sarada_parula.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/3f5613d6-eae9-5cee-a449-a463e19fa372.jpeg)

ただし実は`imwrite`や`imshow`を使う時にわざわざ`ind2rgb`を使う必要がなく、カラーマップを入れたら自動的に変換してくれて便利です。
```matlab
imwrite(arimg_gs,copper,"sarada_copper.jpg")
```

![sarada_copper.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/84755620-10d1-db5b-84f5-75f15624377a.jpeg)

その他にも色んなカラーマップがあるので、それぞれ作って比較してみます。
```matlab
arimg_gs = im2gray(imread("sarada.jpg"));

lis_cmap = ["spring" "summer" "autumn" "winter" ...
    "jet" "parula" "copper" "turbo" ...
    "hot" "pink" "bone" "sky" "abyss","hsv"];

mkdir("saramap")
for cmap = lis_cmap
    imwrite(arimg_gs,eval(cmap),"saramap/"+cmap+".jpg")
end
```

こうやってこんなフォルダができます。

![saramap_folder.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/6de495a5-95e2-c337-3ae1-a34aabc06eec.jpeg)

どんなカラーマップが使えるか[公式サイト](https://jp.mathworks.com/help/matlab/ref/colormap.html)で調べられます。


# フォルダごと画像を読み込む 〔[imageDatastore](https://jp.mathworks.com/help/matlab/ref/matlab.io.datastore.imagedatastore.html)〕

沢山の画像が一緒のフォルダにあって全部使いたい場合は`imageDatastore`を使うのも便利です。機械学習などでもよく使われています。

例えば前の例において作成したフォルダで試します。
```matlab
imds = imageDatastore("saramap")
```
```:結果
imds = 

  ImageDatastore のプロパティ:

                       Files: {
                              '/Users/phyblas/Documents/MATLAB/saramap/abyss.jpg';
                              '/Users/phyblas/Documents/MATLAB/saramap/autumn.jpg';
                              '/Users/phyblas/Documents/MATLAB/saramap/bone.jpg'
                               ... and 11 more
                              }
                     Folders: {
                              '/Users/phyblas/Documents/MATLAB/saramap'
                              }
    AlternateFileSystemRoots: {}
                    ReadSize: 1
                      Labels: {}
      SupportedOutputFormats: ["png"    "jpg"    "jpeg"    "tif"    "tiff"]
         DefaultOutputFormat: "png"
                     ReadFcn: @readDatastoreImage
```

読み込んだら`ImageDatastore`のオブジェクトになって、色んなプロパティとメソッドを持っています。

`.read`メソッドを使ったら一つ画像を読み込んで、もう一度使ったら次の画像を読み込みます。forループとかで一枚ずつ読み込んで処理することができます。
```matlab
imds = imageDatastore("saramap");
for i = 1:length(imds.Files)
    img = imds.read;
    [~,fn] = fileparts(imds.Files{i});
    sx = size(img,2);
    sy = size(img,1);
    fprintf("%10s [%d×%d]\n",fn,sx,sy)
end
```
```:結果
     abyss [540×405]
    autumn [540×405]
      bone [540×405]
    copper [540×405]
       hot [540×405]
       hsv [540×405]
       jet [540×405]
    parula [540×405]
      pink [540×405]
       sky [540×405]
    spring [540×405]
    summer [540×405]
     turbo [540×405]
    winter [540×405]
```

又は`.readall`メソッドを使って一気にcell配列として全部読み込むこともできます。

（cell配列は何なのかまだよくわからない方は[**この記事を呼んでください**](https://qiita.com/phyblas/items/83e10ee040981d08e3aa)）

cell配列になるので、もし4次元の配列にしたいならちょっと工夫が必要です。これもcell配列に関して理解しておいた方がいいと思います。
```matlab
imds = imageDatastore("saramap");
cellimg = imds.readall
allimg = cat(4,cellimg{:});
arrsize = size(allimg)
```
```:結果
allimg =

  14×1 cell 配列

    {405×540×3 uint8}
    {405×540×3 uint8}
    {405×540×3 uint8}
    {405×540×3 uint8}
    {405×540×3 uint8}
    {405×540×3 uint8}
    {405×540×3 uint8}
    {405×540×3 uint8}
    {405×540×3 uint8}
    {405×540×3 uint8}
    {405×540×3 uint8}
    {405×540×3 uint8}
    {405×540×3 uint8}
    {405×540×3 uint8}


arrsize =

   405   540     3    14
```

ちなみに横で連結したいならこう書きます。
```matlab
allimg = [cellimg{:}];
fprintf("%d × %d × %d\n",size(allimg))
```
```:結果
405 × 7560 × 3
```

縦でで連結したいなら`cell2mat`関数を使います。
```matlab
allimg = cell2mat(cellimg);
fprintf("%d × %d × %d\n",size(allimg))
```
```:結果
5670 × 540 × 3
```

`ReadFcn`というキーワードに関数を入れたら、その関数は画像が読み込まれる時にまず適用されて、その関数の返り値が使われます。

例えばグレースケールにしてサイズ変更したいならこう書きます。
```matlab
function arimg = fcn(filenamae)
    arimg = imread(filenamae);
    arimg = im2gray(arimg);
    arimg = imresize(arimg,[300 NaN]);
end

imds = imageDatastore("saramap",ReadFcn=@fcn);
join(string(size(cat(4,imds.readall{:})))," × ")
```
```:結果
    "300 × 400 × 1 × 14"
```


# 画像をいっぱい並んで表示する 〔[montage](https://jp.mathworks.com/help/images/ref/montage.html)〕

沢山の画像を表示する時に`montage`という関数を使うことも多いです。これを使ったら画像が四角形に並んで便利です。

`montage`を使う方法は色々ありますが、例えば4次元の配列に使う場合。試しに適当に作って表示してみます。
```matlab
arimg = zeros(100,100,3,9,"uint8")+100;
arimg(:,:,:,1) = 0;
arimg(:,:,1,2) = 255;
arimg(:,:,2,3) = 255;
arimg(:,:,3,4) = 255;
arimg(:,:,1:2,5) = 255;
arimg(:,:,2:3,6) = 255;
arimg(:,:,[1 3],7) = 255;
arimg(:,:,:,8) = 255;
arimg(31:70,31:70,:,:) = 200;
montage(arimg)
```

![montage0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/066c0244-469d-4bbc-fe80-1b2eebca46bc.png)

`imageDatastore`と使うこともできます。その場合フォルダの中の画像を全部読み込むことになります。
```matlab
montage(imageDatastore("saramap"))
```

![montage_saramap1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/754fbede-00eb-4148-b6b7-5631ed7f69d8.jpeg)

色々キーワードを入れて表示する方法を設定することができます。例えば`Size`は縦と横に並べる数。`BorderSize`は各画像の間の隙間。`BackgroundColor`は背景の色。
```matlab
montage(imageDatastore("saramap"),Size=[4 5],BorderSize=4,BackgroundColor="y")
```

![montage_saramap2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/515839c5-aed0-1e80-5885-a7dcfe313f06.jpeg)

直接画像ファイルの名前を入れて使うこともできます。
```matlab
montage(["saramap/spring.jpg" ...
    "saramap/summer.jpg" ...
    "saramap/autumn.jpg" ...
    "saramap/winter.jpg" ])
```

![montage_saramap3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/d7cd3d9d-6148-d095-7b80-7ee109a3ee6c.jpeg)

3次元の配列に使う場合、無色の画像と見做されます（その場合カラーマップを指定することもできます）。

例えば1枚だけの色画像を使ったら、3枚の無色だ認識されて、3色に分けられてしまいます。
```matlab
montage(imread("sarada.jpg"),bone)
```

![montage_sara.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/97f863d0-cd1a-05ac-c768-e9271d1b9d57.jpeg)


# 画像を並んで連結する〔[imtile](https://jp.mathworks.com/help/matlab/ref/imtile.html)〕

`imtile`は`montage`と似ていますが、表示ではなく一つの大きな画像に合併するのです。
```matlab
arimg = imtile(imageDatastore("saramap"),GridSize=[5 3],BorderSize=5,BackgroundColor=[0.4 0.2 0.1]);
imwrite(imresize(arimg,0.3),"saramap_imtile.jpg")
```

![saramap_imtile.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202903/7b886f04-41c5-a545-e2eb-137d693ee77c.jpeg)


# 参考&もっと読む

- [MATLABによる画像処理・コンピュータービジョン入門](https://qiita.com/tohruk/items/e5f7939b622bcf2e3c4c)
- [1.1 MATLABによる画像処理の基本](https://qiita.com/tohruk/items/4f512d312e6d212f287b)
- [1.2 豊富な可視化機能：MATLAB基本関数](https://qiita.com/tohruk/items/59e527a3e8b540219cc1)
- [2.1.1 各種画像データフォーマットの読込み・書込み](https://qiita.com/tohruk/items/5a04153c079ed5446f59)
- [2.1.2 画像・3次元ボリュームデータ・医用画像(DICOM/NIfTI)の表示](https://qiita.com/tohruk/items/43b3dd1451b99b99cde3)
- [2.1.3 静止画 画像処理・解析のワークフロー](https://qiita.com/tohruk/items/5894fc5787e2a4e7db2e)
- [2.1.4 グラフィックス (マーカー描画・テキスト描画・図形描画)](https://qiita.com/tohruk/items/34c5f05ac8c0d1eb4069)
- [2.3.1 二値化･適応二値化](https://qiita.com/shun-kusano/items/80ab485a709d649f1a03)
- [2.3.4 各種コントラスト調整](https://qiita.com/shun-kusano/items/bccd2fb599c3b278d1d1)
- [【Matlab】自分用忘備録 DeepLearning編](https://qiita.com/RU4_Ryo/items/e718f0484be6c0cabef9)
- [[MATLAB]アフィン変換による変形およびその推定](https://qiita.com/koteko/items/217582480a71df532625)
- [【MATLAB】モザイクアートを手実装する（モノクロ画像編）](https://qiita.com/dokagui_tairan/items/69d9a4d0422fb481f37a)
- [MATLABでPhotoShopの深度ぼかしを再現する。](https://qiita.com/ShunTatsukawa/items/c0ad971232b2069bc6e7)
- [MATLAB でスピード感のあるアニメーション作成](https://qiita.com/backslash/items/0d7815e7beda34bfe302)


# 終わりに

以上MATLABでよく使われる画像処理の基本的な機能を紹介しました。これはただ基本なので、実際にその他にもまだできることが沢山あります。

外部ライブラリ豊富のPythonと違って、MATLABの画像処理機能はほぼ全部公式のものでやり方は統一しているので、安定で覚えやすくて一旦習得したら戸惑うことなくずっと使えそうですね。