ししかわ商店

2019/05/04

M5CameraでQRコードを認識する

M5Stack
placeholdercover image

この記事は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に合わせて数カ所修正しています。

下記のようにしてカメラから画像を取得します。 使い終わったら必ずesp_camera_fb_returnを呼びます。

1
2
3
4
camera_fb_t * fb = NULL;
fb = esp_camera_fb_get();
// カメラ画像を使った処理
esp_camera_fb_return(fb);

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

1
2
3
4
5
6
7
8
9
10
	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

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