この記事はM5Stack Advent Calendar 2018の17日目の記事です。
M5Stack製のカメラモジュール「M5Camera」を使って、QRコードを認識する方法を紹介します。
完成したデモはこちらです。 https://github.com/meganetaaan/m5stack-cam-psram
デモが動く様子のスクリーンキャストです。
M5Cameraを使ってQRコードの読み込みできた! 動画が若干わかりづらいけどディスプレイの左半分に表示したQRコードをカメラで読み取ってて、読み取り結果を右のコンソールに出しています #M5Stack pic.twitter.com/4BTypwhhhE
— ししかわ (@meganetaaan) 2018年12月18日
公式のサンプルをベースに、 カメラの画像からQRコードを認識する処理を追記していきます。
(私が実装した部分はほとんど無く)既存のサンプルコードやライブラリを組み合わせて実現しました。
下記の流れでQRコードを認識します。
- カメラからjpeg画像を取得する
- jpeg画像をグレースケールのビットマップ画像に変換する
- ビットマップ画像を二値化する
- QRコードを検出する
- 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
(カレンダーの〆切を過ぎてしまったため一旦投稿。後日追記します!)