高専プロコン競技部門に参加してました。

第24回高専プロコンに参加してました。

昨年度までは課題・自由などで予選落ちを繰り返してきましたが、今年は卒研も兼ねて競技部門に参加しました(うちは画像処理系の研究室なのです)。
結果は準決勝敗退、初戦の調子の良さを維持できませんでした。

四国高専総合文化祭が終わったので、記事を公開することにします。

今回の競技の着目点(ポイント)

今回の競技は、大きく分けてエンコード部分、パケッティング(うちらの造語)部分、デコード部分の3つに分かれます。
この中で最も(速度的に)ボトルネックになるのは、パケッティング...人間がサイコロを敷き詰める部分にあることは明白です。
私たちは、コンピュータのパワーを使って如何にマンパワーを引き出すかが勝負だと考え、その部分に重点を置いてシステムを構築しました。
顧問教員にも、「人間はシステムの一部として考えろ」と言われていました。
ポイントは、「如何にシンプルにするか」です。

高速なコンピュータ、フレキシブルなヒューマン

コンピュータによる処理は高速です。
しかし、決められたことしかできず,柔軟に行動することは出来ません。
一方、人間の処理は低速ですが、数々の高度な能力と柔軟性を備えています。
人間のその目と脳は、世界最高クラスの画像処理エンジンです。
これらを適切に組み合わせることが出来れば最強だと思いました。

私の担当部分

冒頭で書いたとおり、卒研も兼ねていると言うことで画像処理周りはすべて私の担当でした。
またチームリーダーとして、メンバーへの仕事の割り振りや仕様の策定などを行いました。
毎日の活動を「プロコンノート」にメモしていき、何をしたのか、何を決めたのかを分かるように心がけました(最終的に、ただの落書き帳に成り下がっていましたが)。
f:id:yviscuit:20131022230623j:plain
(プロコンノートの一部。まだ危機感の薄かった夏休み...。)

ほかのメンバーの開発分担は、エンコーダ(全般)とデコーダ(数字→文字列部分)+通信周り+その他補助ツールという割り振りで、後輩の3年生2人に割り振っていました。

旭川に行くまで

北の大地に降り立つまでの間(いわゆる開発期間)に、システムをきちんと作ることが出来ました。
ぎりぎりながら、最後1週間ちょっとはテストランをすることも出来たし、まずまずだったと思います。

サイコロ認識のアルゴリズム

画像処理をやるといっても知識はほとんどなかったので、その勉強から入りました。
その結果考案したアルゴリズムは至ってシンプルで、サイコロ領域の抽出にラベリング+面積計算(最大領域の取得)、個々のサイコロへの分割は等分割(縦の解像度から横の個数を割り出す)、目の数の検出にラベリング+円形度計算を用いています。
あとは目の傾きの検出とかですね。
精度はまずまずで、切り出しがうまくいけばそこそこきちんととれますが、やはりずれると誤差が増えます。
また、6の目の向きの検出にはテンプレートマッチングを採用しました。
これは、目の並びを検出するコードを書くのが面倒だったテンプレートマッチングの精度が思ったほど悪くなかったので、せっかくなので採用してみました。

デコーダのGUI設計

今回はデコーダのウィンドウフレームワークにQtを採用したのですが、これもまた使ったことがなく、ゼロから勉強して実装していました。
(もっと言うと画像処理のバックグラウンドに使ったOpenCVもろくに使えず、ほとんどゼロスタートでした。)
これが実は割と苦しかったです...。
今回、人力での補正が必須だと考えていたため、9月に入った段階で画像処理の改善を止め、人間の手で補正出来るインターフェースを整えていきました。

恋人は君(サイコロ)っていいたい!

今回の競技で一番のボトルネックは、サイコロを詰めるフェースです。
そのため、私たちのチームは敷き詰める訓練を行うプログラムを作成し、それを用いてひたすら5ヶ月間詰め続けた結果、プロコン直前には中サイコロ140個を3分半弱で詰め終えることの出来る速度に到達しました。
(ちなみに、練習をしていない人に詰めさせると8~12分程度はかかります。)
早いのか遅いのかは分かりませんが、予行練習の時に司会の人に「新居浜の詰め方はまるで工場のようですねぇ~」と言われたので、割と早かったのでしょう...。

プロコン1日目

1時間半程度の睡眠の後挑んだ予行練習、そして第1回戦。
この日は直前の月曜日の思いつき通り、顔と手にサイコロのペイントをしてました。
いろんな人の注目を得られて良かったです!

本戦の配属

本戦では私はパケットを詰める方でした。
なんとうちのチーム、デコーダの製作者がパケットを詰めて、エンコーダを書いた人がデコードするという状態になりました。
意図したわけではないのですが、相手のことを考えてUIを設計するいい機会だったのかもしれません。


(先生もこのようなことを言っています。)

本戦第一回戦の結果は4位。
後の解析で、画像が台形にひずんでいたことから、パケットの半分くらいを手動で補正する羽目になっていたようです...。

プロコン2日目

プロコン競技部門は、一晩でどこまで完成度を上げてくるかが勝負の部門です(違います
うちのチームでは、本戦で見つけたバグの修正と、テーブルの効率化を図りました。
しかし、準決勝ではあっけなく敗退。
修正したテーブルにタブ文字が混入し、デコードした文字列に謎の空白があるということになってしまいました。
これはそもそも空白文字を許容しているという仕様の甘さもありました。

総合文化祭に向けて

今回の本戦で見つかったバグを修正し、総合文化祭に挑みました。
さらに、本戦で得た経験から、いくつか追加機能を実装しました。

総合文化祭1回戦

初戦の設定時刻は5分です。
画像の自動取得(クローラ)が正常に稼働しなかったため、人力で画像をダウンロードするというはめに。
おかげさまで、結果は振るわず6高専中5位。
休憩時間の30分を駆使して全力でコードを修正し、きちんと動くようにしました。

総合文化祭2回戦

2回戦の設定時刻は8分。
うちのチームの本領が発揮され、4パケット分を送信、解析できました。
詰めミスもなく、絶好調だったため、2位のチームとダブルスコアの136文字を提出。

総合文化祭3回戦

最終試合は設定時刻10分でした。
しかし、3,4パケット目で詰めミスを起こしてしましました。
さらに、デコーダも解答提出したらエラーが返ってくるなどで大慌て。
結局、3パケット目の途中までしか解答できずに3位。
ちなみにパケットは6パケットまで送ることができ、うまく解析できれば200文字程度は送信できた可能性もありました。

最終成績

順位だけ見ると、とても波が大きくこれは無理かな、と思ったのですが、最終成績は四国で1位となりました。
合計解答文字数が219文字と、2位の134文字に大差をつけて圧勝。
やはり2回戦の調子の良さがひびきました。
しかし、人間の不安定さが大きく影響するため、ここは改善すべき点であるというのもまたうちのチームの問題点として浮き彫りになりました。

プロコン楽しかった。

高専生活最後の年でしたが、プロコンを楽しむことができてよかったです。
後輩にうまく技術継承できたかと言われれば非常に微妙なところですが、それはまた今後やって行かないといけないな、と思います。
また、本戦では思った結果が発揮できませんでしたが、総合文化祭ではそれなりに良い結果も出せたので、良かったのではないかな、と思います。
後輩たちには、今回の経験を来年度以降のプロコンに活かしていってほしいなと思います。
ダメなリーダーでしたが、初音もきゅさん(@Michael_800)、けふぃあさん(@kefia_star)さん、ついてきてくれてありがとうございました。

最後記事を書くのが面倒になったので、言いたいことだいぶ端折った気がします。
気が向いたら追記するかも。