Edited at
M5StackDay 16

M5CameraでQRコードを認識する

この記事はM5Stack Advent Calendar 2018の17日目の記事です。

M5Stack製のカメラモジュール「M5Camera」を使って、QRコードを認識する方法を紹介します。


デモ

完成したデモはこちらです。

https://github.com/meganetaaan/m5stack-cam-psram

デモが動く様子のスクリーンキャストです。


処理の流れ

公式のサンプルをベースに、

カメラの画像からQRコードを認識する処理を追記していきます。

(私が実装した部分はほとんど無く)既存のサンプルコードやライブラリを組み合わせて実現しました。

下記の流れでQRコードを認識します。


  1. カメラからjpeg画像を取得する

  2. jpeg画像をグレースケールのビットマップ画像に変換する

  3. ビットマップ画像を二値化する

  4. QRコードを検出する

  5. QRコードを解析する

ステップ1は公式デモをそのまま使っています。

ステップ2は後続のQRコード読み取りのために必要です。(ただしステップ2と3は同じタイミングでできる=jpegのデコード時に二値画像を計算できるはずですが、それぞれ別のライブラリを使っているためそのままにしています。)

ステップ3~5はこちらのサンプル(ESP32ベースのカメラでQRコードを認識した例)を参考にしつつ、M5Cameraに合わせて数カ所修正しています。


カメラからjpeg画像を取得する

下記のようにしてカメラから画像を取得します。

使い終わったら必ずesp_camera_fb_returnを呼びます。

camera_fb_t * fb = NULL;

fb = esp_camera_fb_get();
// カメラ画像を使った処理
esp_camera_fb_return(fb);


jpeg画像をグレースケールのビットマップ画像に変換する

stbというC/C++向けユーティリティライブラリの画像変換機能を使いました。このライブラリは外部依存が無く、ヘッダを一つ読み込むだけで使えるので便利です。

    unsigned char *pixels;

int width = fb->width;
int height = fb->height;
int bpp = 3; // 入力画像のピクセル辺りのバイト数
int n_channel = 1; // grayscale

// pixelsにはjpgをパースした結果のビットマップがコピーされる
// req_comp = 1を指定するとグレースケールに変換される。
// その時のバッファサイズはピクセル数xチャンネル数 640 x 480 x 1バイト
pixels = stbi_load_from_memory(fb->buf, fb->len, &width, &height, &bpp, n_channel);

その他、詳細はデモのリポジトリを確認してください。

https://github.com/meganetaaan/m5stack-cam-psram

(カレンダーの〆切を過ぎてしまったため一旦投稿。後日追記します!)