LoginSignup
6
7

More than 1 year has passed since last update.

Blazor WebAssembly + OpenCVSharpでブラウザ上で動作するカスタマバーコードリーダーを作成した(実装解説)

Last updated at Posted at 2023-02-17

Blazor WebAssemblyって何?

  • .NET 6や.NET 7で提供されているBlazorフレームワークのモデルの一つ
    • BlazorはWebUIに関するフレームワーク
      • SPA(Single Page Application)方式でブラウザ上にWebページの描画を動的に行う
  • Blazorで使用可能なモデル
    • Blazor Server: 前者はサーバー側で描画処理
    • Blazor WebAssembly: ブラウザ側で描画処理
      • 今回は、後者を使用

Blazor WebAssemlbyの凄いところ

通常ブラウザで動的な描画を行う場合は、JavaScriptによるDOM操作やVue.jsやReactなどのJSフレームワークを使用します。
Blazorでは、C#を中心にWebUIの動的な動作を作成することができます。さらに、.NET系の標準ライブラリを使用することができます。たとえ、ブラウザ上で動作するBlazor WebAssemblyであっても、C#系のプログラムや.NET系のライブラリが動きます。

知っている人は多いと思いますがWebAssmeblyは、ブラウザ上で動作するJavaScript言語に続く第2言語(?)であり、JavaScriptよりも高速に動作します。Blazor WebAssemblyでは、C#からWebAssemblyのバイナリが生成されるので高速な動作が期待できます1

カスタマバーコードって何?

  • 郵便物を大量に出す際に、宛名に印字されていると料金の割引ができるバーコード

    • 下の画像がカスタマバーコード
      image.png
  • カスタマバーコードの仕様は以下のページから

カスタマバーコードリーダーを作成した理由

  • カスタマバーコードを読み取れるスマホアプリがあまりなかったから
    • iOSで動作するアプリはなさそう
  • アプリではなく、ブラウザ上で動作するものがなかったから
    • カスタマバーコードを作成するWebサイトはあっても、読み取りができるものは多分ない
  • 仕事でカスタマバーコードの検証を行う際に役立つ?
  • 単純にBlazor WebAssemblyを使ってみたかった
    • ここ重要

実際に動いているサイト

  • この記事では概要のみ記載します。

  • ソースコードは上のGitHubリポジトリで公開中

仕組みについて

今回、WebUIはBlazor WebAssembly。カスタマーバーコードの読み取りの処理本体は、OpenCVSharp2を使用しています。OpenCVSharpの機能を使用して、画像の加工や画素の参照を行います。
また、作成したWebサイトでは、画像ファイルの読み取りとカメラでの読み取りの2機能を実装しています。
ブラウザ上のみで動作する様にしてあり、アプリケーションサーバーが無くても、WebサーバーのみあればWebサイトを稼働させることができます。

WebAssemblyを使用するにあたっての注意点

実装時に注意が必要なのが、WebAssemblyでは直接DOM操作はできません。
JavaScriptからWebAssemblyを呼び出したり、WebAssemblyからJavaScriptを呼び出すことは可能ですが、WebAssemblyから直接DOM操作は行えないのでJavaScriptを呼び出して操作する必要があります。

ただし、Blazor WebAssemblyのフレームワーク上で用意されている仕組みに乗っかる分にはそこを意識する必要はないです。
基本的には動的な描画はBlazor WebAssemblyが行いますが、イレギュラーな操作(Canvasなど)はJavaScriptによる呼び出しが必要です。

ファイル取り込み機能

ファイル読み取り機能は、ブラウザから画像ファイルを指定することで、ブラウザ上でカスタマーバーコードの読み取りを行う機能になります。

以下のような流れで処理しています。(実際の実装と差異があるので注意)

画像の大きさを変更するのは、画像が大きいと処理時間が長くなり、JavaScriptのタイムアウトに引っかかる可能性があります。
WebAssembly上で画像サイズを変換する方法はありますが、高速で画像サイズ変換可能な方法は無いと思われるので、Canvasの機能で変換する仕組みとしました。

記事執筆時点のOpenCVSharpのWebAssembly版では、BMPデータしか読み込めません。
カスタマバーコード読み取り処理直前に、画像をBMPデータに変換しています。

カメラ取り込み機能

カメラ読み取り機能は、ブラウザからカメラを呼び出し、ブラウザ上でカスタマーバーコードの読み取りを行う機能になります。

以下のような流れで処理しています。(実際の実装と差異があるので注意)

画像を取得し、Canvasにセットするのは、WebAssemblyでは直接カメラの画像を取得できないためです。
一旦、Canvasにセットしてから、ImageURIとして取り出します。

カスタマバーコードの読み取り

Qiitaの記事でバーコード読み取りに関して取り上げている記事があります。バーコードの種類は違いますが大まかな流れは一緒なのでこちらを先に読むと良いです。

以下のような流れで検出しています。(実際の実装と差異があるので注意)

  • 画像の加工
    • 入力画像は、カメラで撮影したものであれば明るさや撮影時の影などがあるので、バーコード検出の邪魔にならないように加工します。

バーコード読み取りのために2値化しますが、OpenCVの標準的な2値化関数だとカメラ撮影時の影をうまく処理できないので、Cv2.AdaptiveThresholdを使用することをおすすめします。

  • 画像の回転
    • カスタマバーコードの読み取りを行う際に、入力画像に対して横方向に読み取りを行います。
      • カスタマバーコードはその性質上、傾きには弱いですので、傾いているものには角度の補正が必要となります。
    • 画像の回転は繰り返し行い、様々な角度でバーコード検出できるようにしました。
      • 本来は、速度面での影響を考えカスタマバーコードの傾きを算出し、それを基に回転するのが効率的ですが、算出アルゴリズムを思いつかなかったのでこのような方法を取りました。多分、傾きを検知するアルゴリズムはあるはずですが、見つからない&思いつきませんでした。
  • バーコード検出
    • 専用のアルゴリズムを用いて検出します(下の項目で説明)。

バーコード検出

バーコードの読み取りを行う際は、画像の行毎で検出を行います。
image.png

下の画像の通り、カスタマバーコード上の画素を通った際にそれがカスタマバーコードであることを検出します。

image.png

ちなみに、カスタマバーコードに傾きがある場合は、下の様にバーコードの全てを通らなくなるため検出できなくなります。なので、バーコード検出前に画像に回転し、検出できるようにしています。
image.png

バーコード検出の流れは、以下のような感じで行っています。(実際の実装と差異があるので注意)

細かい説明は行いませんが簡単に流れを説明するこんな感じです。

  1. バーコードの縦棒67本の検出
  2. バーコードのフォーマットチェック
  3. バーコードのデコード
  4. チェックデジットのチェック(誤検出チェック)
  5. すべて問題が無ければ、デコード結果を格納する

まとめ

機能・ソースコードとしては比較的コンパクトですが、デスクトップアプリケーションに比べて、WebAssemblyやブラウザ事情など複雑な部分があり一筋縄では実装できませんでした。物ができるまで大変だったので、こうして記事をまとめてみました。
あまり洗練されている実装とは言えませんが、どこかの誰かの役に立てればと思います。

  1. もっとも、最近のブラウザはJavaScriptでも十分早いので、特別なケース以外ではJavaScriptでも事足りるとは思いますが。

  2. OpenCVSharpは、OpenCVのC#ラッパー。WebAssemblyにも対応している。GitHub

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7