QRコードの生成のAPIを振り返る(1回目)(そして最終回)

この記事は[OpenCV Advent Calendar 2021](https://qiita.com/advent-calendar/2021/opencv)の25日目の記事です。
他の記事は目次にまとめられています。 

:::note info
QRコード、QR Codeは、デンソーウェーブの登録商標です。
:::

:::note warn
当該記事のタイトルは、@tomoaki_teshimaさん記事のものを参考とさせていただきました。
:::

https://qiita.com/tomoaki_teshima/items/d12af6cc01968f82bcdf

■  "QRコード"機能が追加になったよ!
===================================
2021/12/25に、OpenCV 4.5.5がリリースされる、はず。（順調にいけば）

さて、OpenCV 4.5.5の新機能の１つが **"QRCode"** ですね!!

あれ？ QR Detectorなら昔からある？ Contribにwechat_qrcode？いやいや!! 今年のOpenCV 4.5.5には QR Code **"生成機能"** が搭載されました！


■ OpenCV 4.5.5 から、QR Encoderが搭載されます！(でも、そこ？)
==============================================================

さて、OpenCV 4.5.5のリリースを待っていると多分、クリスマス当日になってしまう。
そこで、`4.x` branchをベースに機能を確認してみる。

……なのですが、え？ `objdetect`にQR Encoderが生えているの？

https://github.com/opencv/opencv/blob/4.x/modules/objdetect/include/opencv2/objdetect.hpp#L670

とりあえず、動かしてみる。

▢ OpenCV 4.5.5のコンパイル(いつもの)
-------------------------------------

このあたりはもう手慣れたものなので、これくらいでいいよね？

```bash
sudo apt install git cmake ninja-build ccache build-essential 
git clone --depth=1 https://github.com/opencv/opencv.git
cmake -S opencv -B opencv_build -GNinja
cd opencv_build 
ninja
sudo ninja install
```

```plaintext
-- General configuration for OpenCV 4.5.5-pre =====================================
--   Version control:               80492d6
--
--   Platform:
--     Timestamp:                   2021-12-20T12:17:41Z
--     Host:                        Linux 5.13.0-22-generic x86_64
--     CMake:                       3.18.4
--     CMake generator:             Ninja
--     CMake build tool:            /usr/bin/ninja
--     Configuration:               Release
```

■ もっともsimpleなテスト(たった7行!実質3行)
============================================
パラメータチューニングも無ければ、なんとたった3行でQR code画像を生成できる!
includeとかも加えても、7行!! 

```c++
#include <opencv2/opencv.hpp>
int main(){
  auto encoder = cv::QRCodeEncoder::create();
  cv::Mat qrcode;
  encoder->encode("Hello,world!", qrcode);
  cv::imwrite("qr.pbm", qrcode);
}
```

使うAPIこれしかないです。 `create`して、`encode`する！以上!簡単!

```c++
    /** @brief Constructor
    @param parameters QR code encoder parameters QRCodeEncoder::Params
    */
    static CV_WRAP
    Ptr<QRCodeEncoder> create(const QRCodeEncoder::Params& parameters = QRCodeEncoder::Params());

    /** @brief Generates QR code from input string.
     @param encoded_info Input string to encode.
     @param qrcode Generated QR code.
    */
    CV_WRAP virtual void encode(const String& encoded_info, OutputArray qrcode) = 0;
```

■ 設定可能なパラメータ
=======================

https://github.com/opencv/opencv/blob/4.x/modules/objdetect/include/opencv2/objdetect.hpp#L697

```c++
    /** @brief QR code encoder parameters.
     @param version The optional version of QR code (by default - maximum possible depending on
                    the length of the string).
     @param correction_level The optional level of error correction (by default - the lowest).
     @param mode The optional encoding mode - Numeric, Alphanumeric, Byte, Kanji, ECI or Structured Append.
     @param structure_number The optional number of QR codes to generate in Structured Append mode.
    */
    struct CV_EXPORTS_W_SIMPLE Params
    {
        CV_WRAP Params();
        CV_PROP_RW int version;
        CV_PROP_RW CorrectionLevel correction_level;
        CV_PROP_RW EncodeMode mode;
        CV_PROP_RW int structure_number;
    };
```

▢ int version
-------------
画素数・情報量。 1(21x21)～40(177x177)の中で選択する。

https://www.qrcode.com/about/version.html


▢ CorrectionLevel correction_level
-----------------------------------
誤り訂正能力。L～Hで選択。誤り訂正能力を高めればその分、記憶できる情報量も減る。

https://www.qrcode.com/about/error_correction.html

```c++
    enum CorrectionLevel {
        CORRECT_LEVEL_L = 0,
        CORRECT_LEVEL_M = 1,
        CORRECT_LEVEL_Q = 2,
        CORRECT_LEVEL_H = 3
    };
```

▢ EncodeMode mode
-----------------
エンコード方法の指定。例えば数字しか入っていないデータならば、MODE_NUMERICを選ぶと情報を効率的に保存できる、など等。

```c++
    enum EncodeMode {
        MODE_AUTO              = -1,
        MODE_NUMERIC           = 1, // 0b0001
        MODE_ALPHANUMERIC      = 2, // 0b0010
        MODE_BYTE              = 4, // 0b0100
        MODE_ECI               = 7, // 0b0111
        MODE_KANJI             = 8, // 0b1000
        MODE_STRUCTURED_APPEND = 3  // 0b0011
    };
```


▢ int structure_number
----------------------
連結機能。複数のQRコードによって１つのデータを表現する機能。使うのはなかなか難しそうですが…。

```c++
    /** @brief Generates QR code from input string in Structured Append mode. The encoded message is splitting over a number of QR codes.
     @param encoded_info Input string to encode.
     @param qrcodes Vector of generated QR codes.
    */
    CV_WRAP virtual void encodeStructuredAppend(const String& encoded_info, OutputArrayOfArrays qrcodes) = 0;
```

■ 一応…
========
画像データは、pixel by pixelな画像データなので、必要なサイズに引き延ばしてください。


■ まとめ
========
- OpenCV 4.5.5 は、クリスマスにリリースだよ！
- なぜかObject Detect機能の中に、QR Code生成機能が生えたよ！
- 使い方は簡単。これでどんどんQRコード生成できるね！やったー！

それでは皆様、良い年をお過ごしくださいませ！！来年もまた元気に会いましょう！！

:::note alert
ただし、私は普通に来週もお仕事である。
:::