図形同士の類似性を判断させてみる vol.1

 今回は複数のセルによって表現される2つの図形の類似性を判断させるプログラムを作ってみる。
 類似性を判断させるに当たって以下の2点のようなことを考えるとする。

  1. 複数の特徴量を用いた図形の定量化(その図形の特徴ベクトルを定義する)
  2. 特徴ベクトルの大きさと方向から類似性を定義する(ユークリッド距離によって類似性を定義する)


 まず、"セルによって表現される図形"をソース上では2次元配列(都合上3次元配列)での二進法で表現する。今回は11×11マスの図形とする。

int cell[][CELL][CELL]={
{
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,1,1,1,1,1,0,0,0},
{0,0,0,1,1,1,1,1,0,0,0},
{0,0,0,1,1,1,1,1,0,0,0},
{0,0,0,1,1,1,1,1,0,0,0},
{0,0,0,1,1,1,1,1,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0}
},
//ただし #define CELL 10

 今回は9つの図形を定義するため、3次元配列としてまとめた。上記の図形に続いて以下8つも同じように定義する(ただし、図形の形は異なる)

 次に定義した図形から以下のような5つの特徴量を用いて、図形を定量化する。("黒画素"とは上記の配列上で1を示す部分)

  • 黒画素数a1
  • 横方向に連続する黒画素数の平均a2
  • 縦方向に連続する黒画素数の平均a3
  • 重心のX座標a4(黒画素が存在する位置のx座標の平均)
  • 重心のY座標a5(黒画素が存在する位置のy座標の平均)

※最も左上のピクセルを(0,0)、右下のピクセルを(10,10)とする

 まず、各特徴量を求める関数をそれぞれ作ってみる。

void cul_a1(struct figure num[]){ //特徴量 a1 を算出
int i=0,j=0,k=0;

while(i!=9){
while(j!=10){
while(k!=10){
num[i].a1+=cell[i][j][k];
k++;
}
k=0;
j++;
}

j=0;
i++;
}

}


 ここで迷うのが(今回に限らずいつも迷うんだけど)繰り返しにwhile文を使うかfor文を使うかということ。

 while文は記述が少なくて楽なんだけど、カウンタの初期化と文末にカウント処理をしないといけないのが面倒くさい。
 for文は記述が面倒くさいけど初期化とカウントが一度にできて便利。

 う〜ん、やっぱこういった繰り返しはfor文のほうが楽かな(笑)まぁ、ここではとりあえずwhile文で勘弁。
 ちなみに黒画素数(要素が1のセル)の数を数えるだけなのでnum[]で宣言されたstruct figure型の構造体がもつint型の変数a1にセルの要素を累加していっているだけ。0なら加算しても変わらないので最終的な合計が黒画素数(要素が1のセル)となる。

全然書いてないけど、とりあえず今回はここまでということで(え
次回はa2,a3,a4,a5の特徴量を算出する関数を作ってみようと思います。