Pythonが嫌いなのでC++版のPytorchで画像認識をやってみる 18日目 コマンドラインオプション対応

# コマンドラインオプションに対応
ソースはここ。
https://github.com/pipimaru1/StreamViewerAI2.1/tree/master/StreamViewerAI2

オプションの意味を順番で指定するのはいかにもダサいので、コマンドラインオプションに対応させた。最近はパーサーを使うのが流行なのかな。調べるといろいろライブラリが出てきたけど、pythonのコードと似せるのが目的のようで、どれも使いにくかった。というわけで昔ながらのfor文とif文でベタベタに書いた↓。若い人には新鮮かもしれない。昔はみんなこんな感じだったね。

```c++
    /*
    ■引数が一つもない
    ・デフォルトの引数を設定 defult.txt, default.onnx, default.namesを探して読み込む。
    ■引数が足りない
    ・リストだけ、
    ■カメラリストファイルが無い
    ・動画モードで起動
    ・メッセージを出す
    ■onnx、namesファイルがない
    ・終了
    ・メッセージを出す
    */

    // コマンドライン引数を取得
    LPWSTR _lpCmdLine = GetCommandLineW();
    // コマンドライン引数を個々の引数に分解
    int nArgs = 0;
    LPWSTR* szArglist = CommandLineToArgvW(_lpCmdLine, &nArgs);
    // エラー処理
    if (szArglist == NULL) {
        std::wcerr << L"CommandLineToArgvW failed" << std::endl;
        return 1;
    }
    //初期値の設定
    url_file = _AI_CAMS;
    onnx_file = _AI_ONNX;
    names_file = _AI_NAMES;

    int i = 0;
    for (i = 0; i < nArgs; i++)
    {
        if (   wcscmp(szArglist[i], L"-l")==0
            || wcscmp(szArglist[i], L"-list") == 0)
        {
            std::filesystem::path _fp(szArglist[i + 1]);
            url_file = _fp.string();
            i++;
        }
        else if (   wcscmp(szArglist[i], L"-x") == 0
            || wcscmp(szArglist[i], L"-onnx") == 0)
        {
            std::filesystem::path _fp(szArglist[i + 1]);
            onnx_file = _fp.string();
            i++;
        }
        else if (   wcscmp(szArglist[i], L"-n") == 0
            || wcscmp(szArglist[i], L"-names") == 0)
        {
            std::filesystem::path _fp(szArglist[i + 1]);
            names_file = _fp.string();
            i++;
        }
        else if (wcscmp(szArglist[i], L"-f") == 0
            || wcscmp(szArglist[i], L"-frame") == 0)
        {
            sleep = _wtoi(szArglist[i+1]);
            i++;
        }
        else if (wcscmp(szArglist[i], L"-c") == 0
            || wcscmp(szArglist[i], L"-change") == 0)
        {
            display_time_seconds = _wtoi(szArglist[i + 1]);
            i++;
        }
 
        else if (wcscmp(szArglist[i], L"-m") == 0
            || wcscmp(szArglist[i], L"-movie") == 0)
        {
            appmode = APPMODE_MOVFILE;
            int msgboxID = MessageBox(NULL, L"動画ファイル読み込みモードで起動します。\n起動後、ファイルメニューから動画ファイルを指定してください。", L"StreamViewerAI2.exe", MB_ICONWARNING | MB_OK);
        }
        else if (wcscmp(szArglist[i], L"-h") == 0
            || wcscmp(szArglist[i], L"-help") == 0)
        {
            std::ostringstream _str_usage("");
            _str_usage <<"引数が１つも無い場合はデフォルト引数で起動します。デフォルト値は下記です。" << std::endl
                << "カメラリスト:  " << _AI_CAMS << std::endl
                << "onnxファイル:  " << _AI_ONNX << std::endl
                << "nmaesファイル: " << _AI_NAMES << std::endl
                << "=======================================" << std::endl
                << "引数を指定する場合" << std::endl
                << "EX: StreamViewerAI2.exe -l cams.txt -x yolov5s.onnx -n coco.names" << std::endl
                << "=======================================" << std::endl
                << "オプション" << std::endl
                << "-l,-list 'カメラリストファイル'" << std::endl
                << "-x,-onnx 'onnxファイル'" << std::endl
                << "-n,-names 'namesファイル'" << std::endl
                << "-c,-change 'カメラ切り替え時間時間[sec]'" << std::endl
                << "-f,-frame 'キャプチャの間隔時間[ms/f]'" << std::endl
                << "-m,-movie 動画ファイル読み込みモード カメラリストファイルは無視" << std::endl
                << "=======================================" << std::endl
                << "カメラリストファイル書き方" << std::endl
                << "カメラ名称,urlアドレス" << std::endl
                << "例" << std::endl
                << "自宅玄関,http://192.168.1.1/cgi-bin/mjpeg?resolution=1920x1080" << std::endl
                << "猫カメラ,http://ID:PW@192.168.1.2/cgi-bin/mjpeg" << std::endl;
            std::string _tmp = _str_usage.str();
            CA2W wStr(_tmp.c_str());
            MessageBox(NULL, wStr, L"StreamViewerAI2.exe", MB_ICONWARNING | MB_OK);
MB_OK);
            return 0;
        }
    }
    if(0)//オプションのチェック
    {    std::ostringstream _str_usage("");
        _str_usage << url_file << std::endl
            << onnx_file << std::endl
            << names_file << std::endl
            <<"sleep[msec]: " << sleep << std::endl
            <<"flamerate[fps]: "<< display_time_seconds << std::endl;
        std::string _tmp = _str_usage.str();
        CA2W wStr(_tmp.c_str());
        int msgboxID = MessageBox(NULL, wStr, L"cxxopts", MB_ICONWARNING | MB_OK);
    }

    //fileのチェック
    if (!std::filesystem::exists(url_file))
    {
        appmode = APPMODE_MOVFILE;
        int msgboxID = MessageBox(NULL, L"動画ファイル読み込みモードで起動します。\n起動後、ファイルメニューから動画ファイルを指定してください。", L"StreamViewerAI2.exe", MB_ICONWARNING | MB_OK);
    }
    if (!std::filesystem::exists(onnx_file))
    {
        CA2W wStr(onnx_file.c_str());
        int msgboxID = MessageBox(NULL, wStr, (LPCWSTR)L"ONNXファイルがありません", MB_ICONWARNING | MB_OK);
        return 0;
    }
    if (!std::filesystem::exists(names_file))
    {
        CA2W wStr(names_file.c_str());
        int msgboxID = MessageBox(NULL, wStr, (LPCWSTR)L"NAMESファイルがありません", MB_ICONWARNING | MB_OK);
        return 0;
    }

```
これだと、オプション値無しでオプションスイッチを指定すると実行時エラーになるなあ。直すのは今度。

あと動画読み込みにも対応した。

つづく