ENGINEER BLOG

ENGINEER BLOG

デジタルホワイトボードでお絵描きゲームしてみた

こんにちは。
イノベーション本部の田中です。

先日オフィスをリニューアルした際にデジタルホワイトボードを導入しました。
通常のホワイトボード機能は勿論、パワーポイントやエクセルなど既存資料にも書き込みができるので、とても便利です。
WindowsとAndroidを搭載しているため、普段PCで使用している業務アプリや、開発したオリジナルアプリも動かすことができるので、活用シーンも多くあります。

せっかくなので、オリジナルアプリを作ってデジタルホワイトボードで動かしてみたいと思います。
今回は簡単なお絵描きゲームを作ってみました!

▼デジタルホワイトボード
whiteboard

1. どんなお絵描きゲーム?

出されたお題の絵を描いて、AIに判定させるゲームです。
今回は簡単に作るために、お題は「犬と猫」に絞りました。
ユーザーが描いた絵が犬なのか猫なのかをAIが判定してくれます。
犬を描いたつもりなのにAIに「猫」と判定されたら、悔しいですよね笑

2. さっそく作ってみる!

2-1. 開発環境

  • Windows 10
  • Python 3.7
  • TensorFlow 1.15.0

2-2. ペイント機能

PythonでGUIを構築・操作するための標準ライブラリTkinterを使って、
ペイント機能を実装していきます。

具体的には以下機能を実装しました。

  • 線を描く
  • 「ペン」と「消しゴム」の切り替え
  • 「ペン」の色変更
  • 描いた絵を保存してAIに渡す

それぞれに対応する部分のコードを見ていきましょう。

線を描く

マウスの左クリックボタンを押したまま移動した場合に座標が取得されます。
その座標を使いcreate_lineで線を引いています。ボタンを離した時は、座標をリセットしています。
デジタルホワイトボードのようなタッチパネル操作の場合は、画面にタッチしながら移動した時とタッチをやめた時にマウスイベントが発生します。

import tkinter as tk
  def create_widgets(self):
    #マウスの左クリックボタンを押したまま移動したとき
    self.canvas.bind('', self.paint) 

    #マウスの左クリックボタンを離したとき
    self.canvas.bind('', self.reset) 

  def paint(self, event):   
    if self.old_x and self.old_y:
      # create_line(始点のx座標,始点のy座標,終点のx座標,終点のy座標,線の太さなどのオプションを指定)
      self.canvas.create_line(self.old_x, self.old_y, event.x, event.y, width=5.0, fill=self.paint_color, capstyle=tk.ROUND)
      self.old_x = event.x
      self.old_y = event.y

  def reset(self, event):
    self.old_x, self.old_y = None, None

「ペン」と「消しゴム」の切り替え

「ペン」と「消しゴム」のボタンが押された時、ボタンの状態(有効・無効)と線の色を変更しています。
無効になっているボタンはグレーアウトされるため、現在のモードが「ペン」なのか「消しゴム」なのかを直感的に判断できます。

import tkinter as tk
  def change_mode(self):
    #「ペン」ボタンが押されたとき
    if self.write_button['state'] == tk.NORMAL:
      # 各ボタンの状態を変更
      self.write_button['state'] = tk.DISABLED
      self.color_button['state'] = tk.NORMAL
      self.erase_button['state'] = tk.NORMAL
      #初期値もしくは、ユーザーが選択した色にする
      self.paint_color = self.color[1] 

    #「消しゴム」ボタンが押されたとき
    else:
      # 各ボタンの状態を変更
      self.write_button['state'] = tk.NORMAL
      self.color_button['state'] = tk.DISABLED
      self.erase_button['state'] = tk.DISABLED
      #線の色を白色にする
      self.paint_color = '#FFFFFF'

「ペン」の色変更

colorchooserモジュールを使うことでダイアログで色を選択できます。
ユーザーが選択した色のカラーコードを変数に格納して、線を描く際に利用しています。

import tkinter as tk
from tkinter import font, colorchooser

  def color_change(self):
    # colorchooserの返り値を変数に格納
    self.color = tk.colorchooser.askcolor() 

    # 返り値のカラーコードをペンの色に設定
    self.paint_color = self.color[1]

描いた絵を保存してAIに渡す

描いた絵をpostscriptメソッドを使って保存します。
保存されるデータの形式は、ps(postscript)で、PNGやJPGではありません。今回は描いた絵の画像をAIに渡したいので、対応しているPNGやJPGに変換します。変換には、画像処理ライブラリPILを使いました。

from PIL import ImageTk, Image, ImageDraw, EpsImagePlugin
import label_image

  def save_image(self):
    # Canvasに描いた画像を保存
    self.canvas.postscript(file='temp.ps',colormode='color')

    # PILでPNG形式に変換
    saveimg= Image.open('temp.ps')
    saveimg.save('temp.png')

    # 変換した画像をAIに渡して判定を行い、結果をテキストで表示
    self.text.set(label_image.labelImageMain('temp.png'))

2-3. AI判定機能

AIの判定部分は、TensorFlowのサンプルを使って画像分類を行いました。学習と画像分類のコードはサンプル通りなので、割愛します。

学習に使う画像データは、以下のようにwebクローリングのフレームワークicrawlerを使うことで簡単に集めることができます。
写真だと画像分類の精度が低いため、今回はtypeとcolorを指定して線画の白黒画像を集めています。

from icrawler.builtin import BingImageCrawler

# 検索エンジンのBingから画像を収集
crawler = BingImageCrawler(storage={'root_dir': 'cats'})
filters = dict(type='linedrawing',color='blackandwhite')
crawler.crawl(keyword="cat", filters=filters,max_num=10)

2-4. 完成画面

完成したお絵かきゲームの画面は以下のようになりました。

output

3. 実行して遊んでみよう

開発したプログラムをデジタルホワイトボード上で実行してみました。
画面をペンでタッチすることで、操作ができていますね。
output1

試しに猫を描いてみました。
AIの結果は・・・・
output2
下手くそな絵ですが、なんとか猫と判断してくれました笑

4.まとめ

今回はデジタルホワイトボードと親和性の高いペイント機能をメインにAIを組み合わせたお絵描きゲームを作ってみました。様々なお題をランダムで出したり、点数を付ける機能を追加することで、より面白くできそうです。

今後も様々な技術の組み合わせを試していき、
デジタルホワイトボードの新しい使い方や、活用領域を見つけていきます。