しぷぜん

しぷぜん

素人プログラマなおいがStep Zero to Oneしていくブログ

畳み込みニューラルネットワークでウォーリーを探そうと思う(その4)

にほんブログ村 IT技術ブログ Pythonへ

こんにちは、なおいです。

前回までで一枚絵のウォーリーに対しては、ウォーリーかウォーリーでないかを判断することができるようになりました。つまり、一応は学習するフェーズが完了したということになります。

 

そのあたりの奮闘は、前の記事はから

ct-innovation01.hateblo.jp

 

 

 

 

AIにどうやって探してもらうか

では、実際にウォーリーを探してもらいましょう。捜索手順は以下の通りで勧めていこうかと思います。

 

  1. 全体画像を読み込む
  2. 左上の端から順に一定の範囲(とりあえず100✕100px)を切り取る
  3. 切り取った画像がウォーリーかどうかを判別する
  • 見つかる→捜索終了
  • 見つからない→少し切り取る箇所をスライドして再度3を実行を繰り返す

 

切り取り→判定→スライド→切り取り・・・・・を永遠繰り返す。

恐らく見つかるまでにかなり時間がかかると思いますが、まずは見つけれるかどうかが第一です。やってみましょう。

 

と思ったけど、間違ったものを見つけてる可能性もあるので全体検索をしていくことにしましょう。

 

プログラムを組む

プログラムを以下のように組みました。

とにかく、読み込んだ画像をある正方形で切り抜いてはウォーリーかどうかを判断するのを繰り返させるという人海作戦的な手法でみつけられるかどうかのみに焦点を絞って進めています。

確実に発見できるようになってから速度の向上などは考えていきます。 

def main():
    # 予測するデータを準備
    train_pathes = ['写真リスト']

    for fil in train_pathes:
        if fil.endswith(".jpg"):
            image = cv2.imread(fil)
            im_gs = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

            point = [0, 0]
            height = 80
            width = 80
            
            imheight, imwidth, channel = image.shape
            print(str(height) + 'px * ' + str(width) +
               'pxの矩形サイズで捜索中...')

            while True:

                clp = im_gs[point[1]:point[1]+height,
                      point[0]:point[0]+width]

                try:
                    clp = cv2.resize(clp, (60, 60))
                    clpflat = clp.flatten()
                    x_train_data_np = np.array(clpflat, dtype=np.float32)
                    x_train_data_reshape = x_train_data_np.reshape(1, 1, 60, 60)
                    x_train_data_reshape /= 255

                    data_input = x_train_data_reshape[0]
                    r_data = return_result(data_input)
                    data = np.argmax(r_data.data)
                except:
                    point,height,width = movepoint(point,height,width,imheight,imwidth)
                    continue

                if data == 1:
                    image = cv2.rectangle(image,(point[0],point[1]),(point[0]+width,point[1]+height),(255,0,0),3),0,0),3)
                point,height,width = movepoint(point,height,width,imheight,imwidth)
                if height > 100 or width > 100:
                    break
                
            plt.imshow(image)
            plt.show()

これに加えて、検索窓(切り抜き窓)をスライドさせる関数と前回使ったウォーリーかどうかを判断させる関数を組合せて完成。

 

AIに実際にウォーリーを探してもらう

実際にかけたファイルは以下の画像。適当に撮った写真だから光で一部飛んでるけど気にしないでください。

f:id:ct-innovation01:20171109142203j:plain

 

はたして結果はどうやら・・・・

 

 

f:id:ct-innovation01:20171109144433p:plain

 

検出しすぎでは???思わず笑いました。若干ウォーリーにもかぶってるけど・・・

枠のサイズを変えたりしてもう一回やったら一応検出してるけど、その他のものもかなりの数検出しちゃってる。

 

f:id:ct-innovation01:20171109144701p:plain

 

んー学習のし直しかな?確かに不正解の教師用データが基本実写のものだったり、別作品の絵だったりと、データとしてはよくない気もします。

という事で、再度AI君に勉強し直してもらいます。学習データに今回間違って検出しちゃったものを入れ込むことにします。

 

ということで、次回はリベンジ編になると思います。