# フレーム間差分オブジェクト抽出
[TOC]
## 0. 準備
:::warning
**@Windowsを使用されている方**
* この実験ではWindowsにおいてもUbuntu環境を利用します。Windowsのコマンドプロンプトで実行しようとすると$ sh script.sh形式のコマンドが実行できません。Ubuntuのインストールが済んでいない場合は、インストールをお願いします。
* Ubuntuのセットアップ時のパスワードが必要になりますので、分かるようにしておきましょう。
* 忘れてしまった場合は、Ubuntuをアンインストールしてから再度インストールしてください。
* Windows11への自動アップグレードでUbuntuにログインできなくなる事例が発生しています。あらかじめWindows11にアップグレードした状態で環境構築を行うか、Windowsの自動アップグレードをしないように設定しておくことをおすすめします。
1. https://waseda.app.box.com/v/virtualmachine/file/1305446015787 を参考に、Visual Studio Codeをインストールしてください。(p.10のセットアップ2-1 までで構いません。**AzureLinuxの設定・接続は必要ありません。**)
2. その後は、web実験書の末尾の[Visual Studio Codeを利用したプログラミング](#Visual-Studio-Codeを利用したプログラミング)に従って、「Remote Development」という拡張機能を導入して進めてください。
**@Macを使用されている方**
* Ubuntuの導入は必須ではありません.
* https://waseda.app.box.com/v/virtualmachine/file/1329441138271 を参考に、Visual Studio Codeをインストールしてください。(p.9のセットアップ(1) までで構いません。**AzureLinuxの設定・接続は必要ありません。**)
分からないことがあれば、**授業時間中、実験TAに直接質問してください**。
( 授業時間外 問い合わせ先:framediff_ta@hamadalab.com )
言語はCを利用します。Javaを履修した方で不安な方は[情報教育 | 早稲田大学 理工メディアセンター](http://www.waseda.jp/mse/web/infotechedu/)を参考にし、プレレポートにおけるプログラミングで予習しておいてください。
:::
この授業はunixベースの環境でコマンドラインを使用することができ、以下のプログラムがインストールされていることを前提としています。
* [gcc](https://gcc.gnu.org/)
* [make](https://www.gnu.org/software/make/)
* [git](https://git-scm.com/)
コマンドラインから実行して、なければツールのインストールを済ませておいてください。
以降の実験ではコマンドラインを使用したプログラムの実行は
```shell
$ command
```
のように表記します。参考までにUbuntuの場合に環境を整えるためには以下を実行してください。
```shell
$ sudo apt install -y build-essential git
```
実行環境は以下の通りです。
```shell
$ gcc --version
gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0
$ make --version
GNU Make 3.81
$ git --version
git version 2.17.1
```
## 1. 予備実験
まず以下のコマンドを実行して、ファイルをダウンロードしましょう。
```shell
$ git clone https://github.com/hmdlab/frame_diff
```
この例では[`git clone`](https://git-scm.com/docs/git-clone)コマンドを使用して[hmdlab/frame_diff](https://github.com/hmdlab/frame_diff)のリポジトリの内容を、新しいディレクトリを作成した中にクローンしています。これ以降の予備実験では入力した画像を左右反転したり、ネガポジ反転したりしましょう。
:::warning
**@WindowsでUbuntu環境で実行している方**
Ubuntu内のファイルの様子は、[こちら](#WindowsでUbuntuのファイルにアクセスする)に従って確認できます。
:::
### 1.1 プログラムの実行
ファイル一式がクローンされたら`src/image_test.c`を開きます。このプログラムは画像を入力として左右反転画像とネガポジ反転した画像、そしてそれぞれのヒストグラムを作成します。今回扱う画像は`images/flower.bmp`にあります。表示してみると以下のような画像になります。

`frame_diff`のディレクトリに移動して、サンプルプログラムをコンパイルし実行してみましょう(`$`を入力する必要はありません)。
```
$ cd path/to/frame_diff #この部分は人によります
$ gcc src/image_io.c src/image_test.c -o bin/image_test
$ bash scripts/image_test.sh
```
これを実行すると`out`に画像ファイルとヒストグラムのデータが出力されます。
 
以下が得られたことを確認してください(**レポートに必要です**)。また、これ以降緑色の枠内に提示するものは全てレポートの作成に必要となるので、保存するのを忘れないようにしてください。
:::danger
**特に左右反転画像とネガポジ反転画像(.bmp)、またそれに対応するヒストグラムのデータ(.tsv)は、この後の作業で上書きするので、先に名前を変えて別途保存しておいてください。**
:::
ここまでの操作で、以下(各自rename済みのもの)が揃っているか確認してください。
:::success
+ [ ] 元画像のヒストグラムデータ(flower_hist.tsv)
+ [ ] 左右反転画像(flower_reflect.bmp)
+ [ ] 左右反転画像のヒストグラムデータ(flower_refl_hist.tsv)
+ [ ] ネガポジ反転画像(flower_invert.bmp)
+ [ ] ネガポジ反転画像のヒストグラムデータ(flower_inv_hist.tsv)
:::
#### 1.1.1 左右反転の中身
ここで何が行われているか、`src/image_test.c`の198行目以降をみてみましょう。
```c=198
for(c=0;c<3;c++){
for(j=0;j<v_size;j++){
for(i=0;i<h_size;i++){
if (reflect_img) {
/* 左右反転操作('-reflect'オプション指定時) */
output_image[c][j*h_size+i]=input_image[c][j*h_size+(h_size-i-1)];
bin=quantize(output_image[c][j*h_size+i]);
} else if (negative_img) {
/* 輝度反転操作('-negative'オプション指定時) */
output_image[c][j*h_size+i]=255-input_image[c][j*h_size+i];
bin=quantize(output_image[c][j*h_size+i]);
} else {
/* 画像操作なし(デフォルト) */
bin=quantize(input_image[c][j*h_size+i]);
}
/* 操作後の画像のヒストグラムデータ */
histograms[c][bin]+=1;
}
}
}
```
198行目のループは色(0:R, 1:G, 2:B)のループ、199-200行目はそれぞれ縦方向と横方向のループです。左右反転操作を行っている204行目は
```c
output_image[c][j * h_size + i] = input_image[c][j * h_size + (h_size - i - 1)];
```
となっています。画像を表す配列はこのプログラムでは\[色\]\[座標\]の形式で保持されており、座標は1次元で表されています。
| | $0$ | $\cdots$ | $i$ | $\cdots$| $h_{size}-1$|
| :-: |:-: |:-: |:-: |:-: |:-: |
| **$0$** | $I^c_{0}$ | $\cdots$ |$I^c_{i}$| $\cdots$|$I^c_{h_{size}-1}$|
| $\vdots$ | $\vdots$ | $\ddots$ |$\vdots$| |$\vdots$|
| **$j$** | $I^c_{j\times h_{size}}$ |$\cdots$ |$I^c_{j\times h_{size}+i}$| $\cdots$ |$I^c_{(j+1)\times h_{size}-1}$|
| $\vdots$ | $\vdots$ | |$\vdots$| $\ddots$ |$\vdots$|
| **$v_{size}-1$** | $I^c_{(v_{size}-1)\times h_{size}}$ | $\cdots$ |$I^c_{(v_{size}-1)\times h_{size}+i}$| $\cdots$ |$I^c_{v_{size}\times h_{size}-1}$|
つまり、二次元座標では$(i,j)$と表されていたものが一次元では$(j\times h_{size}+i)$となっているので、二次元上では$(h_{size} -i -1,j)$の要素を$(i,j)$に代入していた操作は上記の204行目のようになります。
またここで、実際の画像データと、プログラム中の画像を表す配列との対応イメージは以下の通りです。

#### 1.1.2 ネガポジ反転の中身
ネガポジ反転操作ではそれぞれの座標におけるRGBの値を反転する必要があります。208行目では以下のような操作を行っています。
```c
output_image[c][j * h_size + i] = 255 - input_image[c][j * h_size + i];
```
今回RGBの値は8bitの値なので0~255までの値域を持ちます。ネガポジ反転は最大値から現在の値を引くことで実現できます。
### 1.2 ヒストグラムの作成
今回の実験で作成するヒストグラムは以下のようなヒストグラムです。ヒストグラムデータをExcelなどで開きヒストグラムを作成してください。**レポートに掲載する際に作成するので、今すぐに作る必要はありません。**

このデータは各行がビンに含まれる最小値に続いてそのビンに含まれる赤・緑・青の画素値の数が記載された、64-binヒストグラムのデータです(m-binヒストグラムがどのようなグラフかは実験テキストに記載があります)。
```csv
MIN(bin) R[bin] G[bin] B[bin]
0 17 375 595
4 17 166 347
8 29 251 523
12 32 238 913
...
```
---
<br>
提出する際には**必ず**以下の条件を満たしていることを確認してください。
* 縦軸と横軸の記載がある
* 凡例がある
* 系列が一つの場合も説明が重複しますが記載してください。
* また凡例はそれをみて分かるように適宜変更してください。
* 横軸がbin(0から63または1から64)になっている
### 1.3 左上以外を黒塗りにした画像の作成
次に左右反転画像を作っているプログラムの部分にコードを追加・修正し、左上1/4以外を黒塗りにした画像を作成しましょう。左右反転画像を作っているのは`src/image_test.c`の202行目から始まる部分になります。
```C=202
if (reflect_img) {
/* 左右反転操作('-reflect'オプション指定時) */
output_image[c][j*h_size+i]=input_image[c][j*h_size+(h_size-i-1)];
bin=quantize(output_image[c][j*h_size+i]);
}
```
204行で行っている作業により、出力画像の配列の色$c$、座標$j \times h_{\mathrm{size}}+i$の要素に入力画像の色$c$、座標$j \times h_{\mathrm{size}}+(h_{\mathrm{size}}-i-1)$の要素が代入されていきます。ここで$i$は列を表し、$j$は行を表しています。
この204行目のコードに追加・修正を加えて、左上1/4以外を黒塗りにした画像を作成してください。[左右反転の中身](#111-左右反転の中身)で示した説明・画像を参照して、黒塗りで出力する場合の操作(RGBの値が何になるか)について考えてみましょう。
また、書き換える際、`bin=quantize(output_image[c][j*h_size+i]);`は消さないように気をつけてください。
:::info
204行目を書き換えて左上以外黒塗りにした画像を作成しなさい。
:::
書き終えたら[プログラムの実行](#11-プログラムの実行)で行ったように**コンパイルして**実行しましょう。今回は反転画像を作っている部分を置き換えているのでflower_reflected.bmpが置き換わっているはずです。

:::success
+ [ ] 左上以外を黒塗りにした画像(.tsvのヒストグラムデータは必要なし)
:::
### 1.4 グレースケール画像の作成
同様にネガポジ反転をしている部分を書き換えてグレースケール画像を作成します。輝度値$L$の計算式はテキストに書かれている以下の式を利用してください。
$$
L=0.257R + 0.504G + 0.098B + 16.0
$$
ここでRGBはそれぞれ画素の赤緑青の明るさです。RGBの画素値全てを求めた輝度値に変更することでグレースケール画像が作成できます。ネガポジ反転をしている部分はソースコードの206行目から始まります。
```C=206
} else if (negative_img) {
/* 輝度反転操作('-negative'オプション指定時) */
output_image[c][j*h_size+i]=255-input_image[c][j*h_size+i];
bin=quantize(output_image[c][j*h_size+i]);
}
```
:::info
208行目を書き換えてグレースケール化した画像を作成しなさい。
:::
先程と同様に実行して、グレースケール画像を得ます。

:::success
+ [ ] グレースケール画像(.tsvのヒストグラムデータは必要なし)
:::
以上で予備実験は終わりです。
## 2. 実験1
実験1では過去・現在・未来の3枚の連続撮影された写真からオブジェクトを抽出します。また、抽出したオブジェクトが最も誤差なく抽出される閾値を求め、閾値と誤差率の関係のグラフを作成します。
### 2.1 frame_diff.c中の課題に取り組む
`src/frame_diff.c`の[(3)-(5)](https://github.com/hmdlab/frame_diff/blob/master/src/frame_diff.c#L300-L357)を埋めてください。それぞれ実行すべきことは該当の部分に記載があります。また、**追加すべき処理にかかれている変数や関数はすでに用意されており、宣言する必要はありません**。(3)の`diff`などを宣言する必要はありません。以下は模式図になります。

該当場所にコードを書き込み終わったら、`Makefile`のあるディレクトリで
```
$ make
```
を実行して`bin/frame_diff`にバイナリファイルを作成します。引数なしで実行してみると、
```
$ bin/frame_diff
set input file name(t=1) with -in1
frame_diff
-in1 (in: input bmp 1)
-in2 (in: input bmp 2)
-in3 (in: input bmp 3)
-histogram (out: histogram data)
-alpha1 (out: alpha values 1)
-alpha2 (out: alpha values 2)
-theta (in: threshold)
-out (out: output bmp)
[-composite -base (in: base bmp)]
[-ideal (in: ideal mask)]
```
と表示されます。引数を指定する必要があります。書き込んだシェルスクリプトを`scripts/get_masks.sh`に用意したので、これを実行しましょう。
```
$ bash scripts/get_masks.sh
input bmp file(1): images/001.bmp
input bmp file(2): images/002.bmp
input bmp file(3): images/003.bmp
histogram: out/hist.tsv
alpha values(1): out/alpha1vs2.bmp
alpha values(2): out/alpha2vs3.bmp
output file (mask image): out/mask.bmp
ground truth (mask image): images/ideal.bmp
width x length : 640 x 480
theta=10 , error=6.216
10 6.216
program terminated normally
```
`program terminated normally`と表示されれば正しくプログラムが実行されています。`out`にファイルが出力されているので確認しましょう。プログラムを実行すると4種類のファイルが作成されます。
:::success
* [ ] t=1,2の時刻の輝度差分の絶対値の画像(alpha1vs2.bmp)
* [ ] t=2,3の時刻の輝度差分の絶対値の画像(alpha2vs3.bmp)
* [ ] 両者をかけ合わせた結果得られるマスク(mask.bmp)
* [ ] 輝度差分の絶対値のヒストグラムデータ(hist.tsv)
* このファイルに示されるY1、Y2、Y3はそれぞれ過去、現在、未来のフレームを表しています。
:::
これらが正しく得られていることを確認してください。
:::danger
この時の4種類のデータは、以降の閾値変更の操作で上書きされるので、こちらも分かるように先に名前を変えて保存しておいてください。
:::
### 2.2 閾値を変更した場合の誤差
得られたマスク(左)と人間が手で抽出したオブジェクトのマスク(右)を比較してみると、

のように、完全には抽出できていません。これはどの程度の輝度値の違いを閾値として設定するかで変わってきます。先程プログラムを実行した際に
```
theta=10 , error=6.216
```
と表示されていましたが、この`error`が全体の何%を間違えたかどうかを表しています。
閾値は`scripts/get_masks.sh`を開き、書かれているthetaの値を書き換えて、再度実行することで変更できます。この際、10から100までを10刻みで調べて記録し、一番小さい値がありそうな区間を1刻みで探索した結果をグラフにしてください。誤差率が一番小さくなったときの輝度差分の絶対値の画像とマスクを保存します。
:::info
閾値を変化させながらどの時に誤差率が一番小さいかを探した上で、その時の輝度差分の画像とマスク画像を保存しなさい。また、閾値と誤差率の関係をグラフにしなさい。
:::
:::warning
10から100まで10刻みで記録すると10点、最小と思われるところで1刻みで調査するのでX1~X9で9点、合計で最低でも19点のグラフになることに注意してください。
:::
この作業の終了後、以下の4つのファイルがあることを確認してください。
:::success
* [ ] 最適な閾値のときのt=1,2の時刻の輝度差分の絶対値の画像
* [ ] 最適な閾値のときのt=2,3の時刻の輝度差分の絶対値の画像
* [ ] 最適な閾値のときの両者をかけ合わせた結果得られるマスク
* [ ] 閾値と誤差率の関係のグラフ
:::
---
### 2.3 実験終了の報告
これで第一週の実験は終わりです。最小となる閾値を実験TAに報告して、正しければ実験は終了です(複数ある場合はそのうちの一つを報告してください)。
以下のチェックリストを参考にして全てのファイルがあることを確認しておいてください。次週上書きしてしまわないように**必ず別の場所にもコピーをとっておくようにしてください**。
* 予備実験
* [ ] 入力画像(花)のヒストグラム
* [ ] 左右反転画像
* [ ] 左右反転画像のヒストグラム
* [ ] 画素値反転画像
* [ ] 画素値反転画像のヒストグラム
* [ ] 左上だけ残した画像
* [ ] グレースケール画像
* 実験1
* [ ] θ=10のときのオブジェクト領域候補1
* [ ] θ=10のときのオブジェクト領域候補2
* [ ] θ=10のときのオブジェクト領域マスク
* [ ] θ=10のときの輝度フレーム間差分値のヒストグラム(hist.tsv)
* [ ] θが最適なときのオブジェクト領域候補1
* [ ] θが最適なときのオブジェクト領域候補2
* [ ] θが最適なときのオブジェクト領域マスク
* [ ] 閾値と誤差率の関係のデータ(各自メモしたもの)
また、来週の実験に向けて以下の準備をしてきてください。
* [ ] 3枚の連続撮影写真
* 実験書2.5に記載の注意事項にしたがって撮影を行ってください。
* [ ] 合成する背景写真
* 連続画像とは異なるものを撮影してください。
## 3. 実験2
実験2では各自で撮影した過去・現在・未来の3枚の連続撮影された写真からオブジェクトを抽出し、オブジェクトが最も誤差なく抽出される閾値を用いて画像合成を行います。また、メディアンフィルターの実装を行います。
### 3.1 frame_diff.c中の課題に取り組む
`src/frame_diff.c`の[(7)](https://github.com/hmdlab/frame_diff/blob/master/src/frame_diff.c#L376-L413)を埋めてください。これによって連続写真と背景画像から合成画像を作成します。それぞれ実行すべきことは該当の部分に記載があります。また、**追加すべき処理にかかれている変数や関数はすでに用意されており、宣言する必要はありません**。模式図は以下になります。

該当場所にコードを書き込み終わったら、`Makefile`のあるディレクトリで`make`を実行してから`bash scripts/composite.sh`を実行してみましょう。
```shell
$ make
gcc src/frame_diff.c src/image_io.c src/median_filter.c -o bin/frame_diff
$ bash scripts/composite.sh
input bmp file(1): images/001.bmp
input bmp file(2): images/002.bmp
input bmp file(3): images/003.bmp
histogram: out/hist.tsv
alpha values(1): out/alpha1vs2.bmp
alpha values(2): out/alpha2vs3.bmp
output file (mask image): out/mask.bmp
width x length : 640 x 480
program terminated normally
input bmp file(1): images/001.bmp
input bmp file(2): images/002.bmp
input bmp file(3): images/003.bmp
base bmp file: images/cambridge.bmp
histogram: out/hist.tsv
alpha values(1): out/alpha1vs2.bmp
alpha values(2): out/alpha2vs3.bmp
output file (mask image): out/composite.bmp
width x length : 640 x 480
program terminated normally
```
これによってマスク画像が`out/mask.bmp`に、合成画像が`out/composite.bmp`に生成されます。

### 3.2 パソコンへの写真取り組み、画像フォーマット変換
次に各自撮影してきた写真を準備しましょう。
:::success
* [ ] 連続写真(3枚)
* [ ] 背景写真(**連続写真の背景とは異なるもの**)
:::
準備ができたらこれらを全て640×480、24bit、拡張子は.bmpに変換した後`images`に取り込みましょう。
変換には[こちらのサイト](https://online-converting.com/image/convert2bmp)などが利用可能です。このサイトを利用した変換方法は末尾の[画像の変換](#画像の変換)に記載しておきます。
:::spoiler .bmpに変換した画像の一部が黒塗りになってしまう場合
変換サイトの性質上、画像の一部が上手く出力されず黒塗りになってしまうことがあります。
* 画像の下部のみであったり、オブジェクトの領域自体に影響がなければ、そのままでも構いません。
* Windowsの場合、画像を開いて「…」のオプションから「画像のサイズを変換」を選択し、予めサイズを『640×480』(あるいはそれに近いサイズ)にリサイズしてから変換サイトを利用すると、改善する場合があります。
* 画像の状態について、ご自身で判断できない場合はTAに確認を取ってください。
:::
<br>
:::warning
**@WindowsでUbuntu環境で実行している方**
Ubuntu内のファイルの様子は、[こちら](#WindowsでUbuntuのファイルにアクセスする)に従って確認できます。
用意した画像をコピーして、該当のUbuntu内のディレクトリに貼り付けることで、自身で用意した画像を入力として実行できるようになります。
:::
### 3.2 合成画像の作成
変換が終わったファイルを引数で指定する必要があります。`scripts/composite.sh`を開き、`-in1`,`-in2`,`-in3`(連続写真)、`-base`(背景写真)の引数を用意した画像のパスに変更しましょう。
```sh=10
IN1="images/001.bmp" # このimages/ の後ろを変更する
IN2="images/002.bmp" # このimages/ の後ろを変更する
IN3="images/003.bmp" # このimages/ の後ろを変更する
BASE="images/cambridge.bmp" # このimages/ の後ろを変更する
THETA=10 # ここを変更する
```
:::info
閾値を変化させながら合成画像を出力し、最も綺麗に合成されたときの輝度差分の画像と合成画像を保存しなさい。
:::
なお閾値は、`scripts/composite.sh`を開き、書かれているTHETAの値を書き換えて、再度実行することで変更できます。
:::spoiler `Can't open input file`の様なエラーメッセージが出る場合
まずは,画像のパスが正しく書けているか
ファイルの権限設定がうまく行っていない可能性があります。**imagesの中のファイルに対して**`chmod 644 *`で読み取り権限を与えてください。
```shell
[frame_diff/images]$ ls -lah
drwxrwxr-x@ 17 user user 544B 11 29 17:37 .
drwxr-xr-x@ 13 user user 416B 12 2 13:17 ..
-rw-r--r--@ 1 user user 900K 11 29 17:35 001.bmp
-rw-r--r--@ 1 user user 900K 11 29 17:35 002.bmp
----------@ 1 user user 900K 11 29 17:35 IN1.bmp # 読み取り権限がない
...
[frame_diff/images]$ chmod 644 *
[frame_diff/images]$ ls -lah
drwxrwxr-x@ 17 user user 544B 11 29 17:37 .
drwxr-xr-x@ 13 user user 416B 12 2 13:17 ..
-rw-r--r--@ 1 user user 900K 11 29 17:35 001.bmp
-rw-r--r--@ 1 user user 900K 11 29 17:35 002.bmp
-rw-r--r--@ 1 user user 900K 11 29 17:35 IN1.bmp # 権限が変わる
...
```
:::
<br>
:::warning
このとき"綺麗"とは主観です。今回は手作業で得られた正解のマスク画像がないので、誤差を測定する対象がありません。(=error rateは出力されません)
ポストレポートには閾値を得るためにどのような基準をもうけたかを記載してもらいますので、その閾値を他人が再現できるように意識しながら閾値を選択してください。
:::
この作業の終了後、以下の2つのファイルがあることを確認してください。
:::success
* [ ] 最適な閾値のときのオブジェクト領域マスク
* [ ] 最適な閾値のときに抽出したオブジェクトと背景写真との合成画像
:::
### 3.3 median filterの実装
median filterを用いた合成画像を作成します。まず`median_filter.h`を`src/frame_diff.c`の冒頭でincludeしてみましょう。
```C=34
#include <string.h>
#include "image_io.h"
#include "median_filter.h" // これを追記する
```
これで`median_filter.c`に定義された関数:`MedianSmoothing()`が利用可能となりました。プレレポートで調べたmedian filterの効果や目的を踏まえ、**どの段階に適用するとどのような効果が得られるのかを考えた上で**、この関数を`src/frame_diff.c`の適切な位置に記述しましょう。
今回median filterを適用する候補(とその適用コード)として考えられるものは以下の通りです。**一箇所以上選択して**メディアンフィルタをかけてみましょう。
* 撮影写真(T x RGB x POS)
* `MedianSmoothing(input_bmp_image[0],h_size,v_size,3);`
* `MedianSmoothing(input_bmp_image[1],h_size,v_size,3);`
* `MedianSmoothing(input_bmp_image[2],h_size,v_size,3);`
* グレイスケールの撮影写真(T x POS)
* `MedianSmoothing(input_grey_image,h_size,v_size,3);`
* フレーム間差分の絶対値(T x POS)
* `MedianSmoothing(alpha_values,h_size,v_size,2);`
* オブジェクト領域候補(ΔT x RGB x POS)
* `MedianSmoothing(cand_mask[0],h_size,v_size,3);`
* `MedianSmoothing(cand_mask[1],h_size,v_size,3);`
* オブジェクト領域(RGB x POS)
* `MedianSmoothing(actual_mask,h_size,v_size,3);`
:::warning
フィルタを適用する場合には**対象が生成された後かつ次の処理に使用される前に適用しなければならない**ことに注意しましょう。合成が終わった後に撮影写真にフィルタを適用しても合成写真はスムージングされません。
:::
該当場所にコードを書き終えたら、再度`Makefile`のあるディレクトリで`make`を実行した後に`scripts/composite.sh`を実行してみましょう。
:::info
median filterを適用した合成画像を保存しなさい。この際閾値は先ほど調べた最適な閾値を用いなさい。またmedian filterあり/なしの出力画像を比較し、想定した効果が得られたかどうかを確認しなさい。
:::
この作業の終了後、以下の2つのファイルがあることを確認してください。
:::success
* [ ] 最適な閾値のときのオブジェクト領域マスク(median filterあり)
* [ ] 最適な閾値のときに抽出したオブジェクトと背景写真との合成画像(median filterあり)
:::
:::warning
このとき、median filterなしの場合と同じファイル名で上書きされるので、median filterなしの出力ファイル名を変更するなどの必要があります。
:::
---
これで第二週の実験は終わりです。以下のチェックリストを参考にして全てのファイルがあることを確認しておいてください。
* 実験2
* [ ] 入力画像(自分で用意した連続写真3枚、背景画像)
* [ ] θが最適なときのオブジェクト領域マスク(median filterなし)
* [ ] θが最適なときの合成画像(median filterなし)
* [ ] θが最適なときのオブジェクト領域マスク(median filterあり)
* [ ] θが最適なときの合成画像(median filterあり)
* [ ] frame_diff.cのソースコード
* [ ] median_filter.cのソースコード
* [ ] median_filter.hのソースコード
---
# 4. ポストレポートの記述にあたって
## 4.1 チェックリスト
### ポストレポートに必要なもの
* 入力画像
+ [ ] 入力画像(花)
+ [ ] 入力画像(子供 x3)
+ [ ] 連続写真 x3
+ [ ] 背景
+ 予備実験
+ [ ] 入力画像(花)のヒストグラム
+ [ ] 左右反転画像
+ [ ] 左右反転画像のヒストグラム
+ [ ] 画素値反転画像
+ [ ] 画素値反転画像ヒストグラム
+ [ ] 左上だけ残した画像
+ [ ] グレースケール画像
+ 実験1
+ [ ] オブジェクト領域候補1 (alpha1) [theta=10のとき]
+ [ ] オブジェクト領域候補2 (alpha2) [theta=10のとき]
+ [ ] オブジェクト領域画像 (mask) [theta=10のとき]
+ [ ] 輝度フレーム間差分値のヒストグラム (hist) [theta=10のとき]
+ [ ] オブジェクト領域候補1 (alpha1) [theta=最適値のとき]
+ [ ] オブジェクト領域候補2 (alpha2) [theta=最適値のとき]
+ [ ] オブジェクト領域画像 (mask) [theta=最適値のとき]
+ [ ] 閾値と誤差率の関係
+ 実験2
+ [ ] オブジェクト領域画像 (mask_fix) [medan filter無し]
+ [ ] 合成画像 [median filter無し]
+ [ ] オブジェクト領域画像 (mask_fix) [medan filter有り]
+ [ ] 合成画像 [median filter有り]
+ ソースコード
+ [ ] frame_diff.cの差分(下記に注意事項の記載があります)
+ [ ] median_filter.c
## 4.2 今回使用したコードの変更部分の報告
```shell
$ git diff -w src/frame_diff.c > diff.patch
```
を実行すると、今回のプログラムで行なった変更を記載したファイル(`diff.patch`)を作成することができます。中身は以下のようになっています。
```diff
diff --git a/src/frame_diff.c b/src/frame_diff.c
index a9f4245..6c513bb 100644
--- a/src/frame_diff.c
+++ b/src/frame_diff.c
@@ -313,7 +313,7 @@ float
* input_grey_image[1][pos]とinput_grey_image[2][pos]を元に計算する
* --------------------------------------------------------------- */
/* ここから */
-
+ diff = abs(input_grey_image[0][pos] - input_grey_image[1][pos])
/* ここまでに記述 */
} /* for (i) */
```
この内容をレポートに含めてください。コードの掲載方法は`コード提出サンプル.pdf`をサンプルとして配布しますのでこちらも参考にしてください。
---
## 補足内容
### 画像の変換
[https://online-converting.com/image/convert2bmp](https://online-converting.com/image/convert2bmp)を利用した画像の変換方法

### Visual Studio Codeを利用したプログラミング
主にWindows環境を利用している方でプログラミングが初めての方は、Visual Studio Codeを利用したプログラミング環境の整備をお勧めしています。これに関して末尾に記載しておきます。
#### WindowsにVisual Studio Codeをインストール
[Visual Studio Code - Code Editing. Redefined](https://code.visualstudio.com/#alt-downloads)

初めに、こちらの[サイト](https://sukkiri.jp/technologies/devtools/vscode_win.html)などを参考に、vscodeを自身のPCにインストールしてください。
#### WindowsでWSL環境を利用する
次に、vscode上でWSL環境を利用するため、Remote Developmentという機能を利用します。
導入手順は以下の画像を参考にしてください。




新しいwindowが立ち上がるので、そちらで実験を進めてください。
実際に利用している様子がこちらです。

#### (利用例)Hello Worldを出力させる
vscodeを利用してHello Worldを出力させる例を以下の画像に示しますので、参考にしてください。





### WindowsでUbuntuのファイルにアクセスする
以下の流れで確認できます。
1. Windows Explorerを開く
2. ネットワークを選択
3. ネットワークのアイコンをクリックし、「¥¥wsl$」を打ち込みEnterを押す(画像1枚目)
4. 「Ubuntu」と名前のついたファイルが出てくる(画像2枚目)
<img src="https://hackmd.io/_uploads/BkRwnljE6.png" width="400">
<img src="https://hackmd.io/_uploads/HkAhhls4p.png" width="400">