Blazor WebAssemblyでつくったマークシートシステム Mark2をオープンソースとして公開

# Mark2のデモ

WebAssemblyを実行可能なWebブラウザーでMark2のページを開きます。

https://omr.mark2.org

サンプルファイルを用意しましたので、デモを実行する場合はダウンロードしてください。

https://mark2.sfc.keio.ac.jp/ja/wp-content/uploads/2022/12/M2-01-001.zip

1. Mark2のページで`座標ファイルの読み込み`ボタンをクリックして`M2-01-001_座標ファイル.xlsx`を指定します。
1. `画像ファイルの読み込み`ボタンをクリックして`image_001.jpg` `image_002.jpg` `image_003.jpg`を指定します。
1. `マーク認識を開始`ボタンをクリックすると処理が開始して、結果をダウンロードすることができます。

![ScreenShot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238166/eccf3a86-e39e-1daf-f702-71f224cadbb5.png)

# はじめに

マークシートの実施には専用のマークシート用紙と読み取りの機械を使うことが一般的です。2006年頃に大学のある研究プロジェクトを紹介してもらって行ってみると、家庭用のプリンターで印刷した調査票にマーク欄がありました。その調査票を家庭用のスキャナーで読み取った画像ファイルをJavaのデスクトップアプリで処理すると、画像処理でマークシートの記入結果がファイルに出力されました。その研究プロジェクトでは[学校評価](https://www.mext.go.jp/a_menu/shotou/gakko-hyoka/)に関する研究の一環として教育現場で安価に利用できる[SQS](http://sqs2.net/)というマークシートシステムを開発していて、私自身はマークシートシステムと連携して動作するデータ分析システムを開発することになりました。


当時は大学と社会がもっと連携していかなければと言われはじめた時期で、私自身もコンピューターの研究室で企業との共同研究に参加したりしていたのですが、その研究プロジェクトでは多くの自治体と連携していて、これまでとはちょっと違った感覚が新鮮でした。ただ、インターネットや情報機器が急速に普及していく中で、マークシートという伝統的な手法がいつまで必要とされるのだろうとは思いました。

それから15年あまりが経過して、実際にアンケートの実施方式としてはWebアンケートが普及していきました。今はマークシートだけでなく紙を利用したアンケートも少なくなったように思います。それでも私から見えている範囲では **調査対象者が情報機器を利用できない環境（マークシート形式の学力調査など）と調査対象者に高齢者が含まれる場合（自治体が実施する幅広い年齢層を対象にした住民アンケート調査など）** では引き続きマークシートのニーズがあるように思います。

SQSは調査票をXMLで拡張することが可能で、その機能を利用して様々なフィールドでマークシートを利用してきました。さらに簡単に使うことができるマークシートシステムについて検討していき、いろいろな人たちの協力のおかげで完成したシステムが **Mark2** です。

# なぜBlazor WebAssemblyか

Mark2はBlazor WebAssemblyで開発しています。Blazor WebAssemblyに辿り着くまでには少し遠い道のりがありました。

## Webアプリを検討

これまでのマークシートシステムのユーザーの状況から、システムは **(1) インストールが簡単 (2) クロスプラットフォームで動作** が重要だろうと考えました。最初に思いついたのがWebアプリだったのですが、Webアプリはスキャン画像を大量にアップロードする必要があり、それが障害となりました。これは災害の被災地でマークシートを利用したアセスメント調査をした経験から、ブロードバンド接続を想定できない環境に対応する必要性を感じたためでした。

## Electronを検討

クロスプラットフォームのデスクトップアプリを構築するためにElectronの採用を検討しました。しかし、技術的な検証のためにNode.jsでマーク認識の画像処理をするプログラムを作成して実行してみると、その動作がとても遅いことがわかりました。検証プログラムでは画像処理ライブラリに[Jimp](https://github.com/oliver-moran/jimp)を利用していて、ネイティブライブラリを利用する方法も検証してみたのですが、当時は動作させることができずに断念しました。

## クロスプラットフォームをあきらめUWPへ

2018年にクロスプラットフォームをあきらめてWindows向けにUWPで開発したデスクトップアプリが[Mark2 Desktop](https://apps.microsoft.com/store/detail/mark2-desktop/9NRJC7500P6M?hl=ja-jp&gl=jp)になります。動作速度も十分で問題なかったのですが、macOSのユーザーは仮想マシンでWindowsを起動してMark2 Desktopを使っていたので、クロスプラットフォームを実現できなかったことは心残りでした。

## そしてBlazor WebAssemblyへ

2021年春に知り合いの先生とオンラインでミーティングをしていました。そのときに学生からAzure Cognitive Servicesの話を久しぶりに聞いたらいろいろと進歩していたので、あとで自分でもMicrosoftやAzureの情報を調べてみようと思いました。そのときに目に止まったのがBlazor WebAssemblyです。

Mark2 DesktopでC#による画像処理は経験がありましたし、WebAssemblyならクロスプラットフォームも実現できると期待して開発をスタートしました。2021年夏にシンプルなプロトタイプが完成したのですが、動かしてみると動作が遅い。このパターンもやっぱりだめかなと思っていたら、利用可能になったばかりのAOTコンパイルの情報を見つけました。

https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-net-6-preview-4/

AOTコンパイルを有効にして動作させてみると十分な性能を得ることができました。このときは本当にうれしかったです。その後、開発を進めてMark2をリリースしました。

Blazor WebAssemblyのAOTコンパイルに関する情報は昨年のQiitaアドベントカレンダーのプレゼントカレンダーに投稿して、日本マイクロソフト賞の最優秀賞をいただくことができました。

https://qiita.com/kaorumori/items/88d836fab1fcbbbb7114

https://blog.qiita.com/adventcalendar-2021-presents-qiita-winners/

# オープンソースとして公開

Mark2をリリースして1年以上が過ぎました。2022年はある自治体で大規模に利用してもらうこともできました。これはひとつの区切りかと考えて、Mark2をオープンソースとして公開するための調整をしました。

もう少しソースコードをきれいに書きたいところとか、C#っぽくないかもと思う書き方のところとか、修正したいところはいくつかありますが、まずは公開することにしました。

## GitHub: mark2-omr/Mark2

https://github.com/mark2-omr/Mark2

Blazor WebAssemblyのアプリで、Mark2の本体になります。

## GitHub: mark2-omr/mark2-ort

https://github.com/mark2-omr/mark2-ort

Mark2には手書き数字認識の機能があり、ONNX形式のモデルを利用しています。`mark2-ort`は[ONNX Runtime Web](https://www.microsoft.com/ja-jp/events/azurebase/blog/onnx-runtime-web-ml_model_in_browser/)のバンドルファイルを生成するコードです。将来的にML.NETがONNX形式のモデルをロードできるようになれば必要なくなるかもしれません。

# 利用者向けWebサイト

https://mark2.sfc.keio.ac.jp/ja/

利用者向けWebサイトはまだ作成中です。Mark2に対応したマークシートの作り方や一般的なテンプレートについて情報発信していく予定です。

# おわりに

Mark2をオープンソースとして公開してひとまずの区切りではありますが、（既存の利用者に配慮しながら）新しい取り組みもしていきたいと思っています。まずは.NET 8でのマルチスレッド対応を次の目標として考えています。あとは手書き数字認識の精度がまだまだ課題で、これは学習モデルだけでなく学習データの整備や画像の前処理も含めて考えていく必要がありそうです。

もし興味をお持ちの方がいらっしゃれば、その他にもおもしろそうなアイディアやソースコードの改善など、みなさんからのコントリビュートをお待ちしています。