JPEG で画像を取得する (c++/Visual Studio)

 

本ページは i-PRO株式会社 の有志メンバーにより記載されたものです。
本ページの情報は ライセンス に記載の条件で提供されます。

 

 

 

本ページでは、i-PRO カメラとPCを JPEG により接続してPC画面へ表示するプログラムを c++ (Visual Studio) で作成する例を紹介します。とても短いプログラムで i-PRO カメラの映像を見ることができます。動作確認は i-PRO mini (WV-S7130)、モジュールカメラ(AIスターターキット)を使って行いましたが、ほとんどの i-PRO カメラでそのまま利用できるはずです。ぜひお試しください。

Python の記事は こちら を参照ください。

[動画] JPEG でカメラと接続して映像表示した様子

 


 

"i-PRO mini" 紹介:

i-PRO mini 画像

 

"モジュールカメラ" 紹介:

AI スターターキット 画像(1) AI スターターキット 画像(2)

 

カメラ初期設定についてはカメラ毎の取扱説明書をご確認ください。

カメラのIPアドレスを確認・設定できる下記ツールを事前に入手しておくと便利です。

 


 

1. JPEG 表記仕様

i-PRO カメラと接続するための JPEG 表記仕様は こちら を参照ください。

 

 

2. 準備

本ページで紹介するプログラムは、下記2つのライブラリを使用します。下記記事を参考にこれらのライブラリをインストールしてください。

(1) OpenCV

(2) libcurl

 

2-1. OpenCV をインストールする

OpenCV のインストール方法、Visual Studio プロジェクトへの設定方法などは下記ページを参考に行ってください。本ページでは説明を割愛します。

OpenCV をインストールする

 

 

2-2. libcurl をインストールする

標準 c++ 言語にはネットワーク関連処理を行うためのライブラリが脆弱ですので、本ページでは libcurl というオープンソースライブラリを使用して機能を実現します。libcurlは複数のプラットフォームで同じようにビルド、稼動させることができるフリーで使いやすいクライアントサイド URL 転送ライブラリです。Microsoft Visual Studio からも利用可能です。

ここでは Microsoft が提供する vcpkg というクロスプラットフォームのパッケージマネージャーを使用して libcurl を導入する手順を紹介します。vcpkg を使用することで、c/c++ の外部ライブラリを利用したい場合に手動でソースコードからビルドすることなくインストールやリンクを簡単に行えるようになります。依存関係も vcpkg が解決してインストールしてくれます。vcpkg は Windows、Linux および MacOS に対応しているようです。

 

[評価環境]

コンパイラ : Visual Studio 2022 pro., Version 17.5.1
ライブラリ : curl:x64-windows, 7.88.1
OS : Windows11 home, 22H2

 

(1) vcpkg をインストール

git の clone コマンドを使用し、GitHub から vcpkg リポジトリをクローンします。任意の場所で実施してください。私は Documents フォルダ内に Github フォルダを作成してここで作業しました。

git clone https://github.com/Microsoft/vcpkg.git

[実行例]

C:\Users\foo\Documents\Github>git clone https://github.com/Microsoft/vcpkg.git
Cloning into 'vcpkg'...
remote: Enumerating objects: 181622, done.
remote: Total 181622 (delta 0), reused 0 (delta 0), pack-reused 181622
Receiving objects: 100% (181622/181622), 68.57 MiB | 3.37 MiB/s, done.
Resolving deltas: 100% (115829/115829), done.
Updating files: 100% (9787/9787), done.

C:\Users\foo\Documents\Github>

 

(2) vcpkg 実行ファイルを生成

クローンした中にある bootstrap-vcpkg.bat を実行して実行ファイルを生成します。

cd vcpkg
bootstrap-vcpkg.bat

[実行例]

C:\Users\foo\Documents\Github>cd vcpkg

C:\Users\foo\Documents\Github\vcpkg>bootstrap-vcpkg.bat
Downloading https://github.com/microsoft/vcpkg-tool/releases/download/2023-02-16/vcpkg.exe -> C:\Users\foo\Documents\Github\vcpkg\vcpkg.exe... done.
Validating signature... done.

Telemetry
---------
vcpkg collects usage data in order to help us improve your experience.
The data collected by Microsoft is anonymous.
You can opt-out of telemetry by re-running the bootstrap-vcpkg script with -disableMetrics,
passing --disable-metrics to vcpkg on the command line,
or by setting the VCPKG_DISABLE_METRICS environment variable.

Read more about vcpkg telemetry at docs/about/privacy.md

C:\Users\foo\Documents\Github\vcpkg>

 

(3) vcpkg install コマンドで curl をインストール

vcpkg install コマンドにより curl をインストールします。ここでは triplet として "x64-windows" を指定します。

triplet とは環境を表す文字列で、対応している triplet は vcpkg help triplet コマンドで確認できます。

vcpkg install curl:x64-windows

[実行例]

C:\Users\foo\Documents\Github\vcpkg>vcpkg install curl:x64-windows
Computing installation plan...
The following packages will be built and installed:
    curl[core,non-http,schannel,ssl,sspi]:x64-windows -> 7.88.1
  * zlib[core]:x64-windows -> 1.2.13
Additional packages (*) will be modified to complete this operation.
Detecting compiler hash for triplet x64-windows...
Restored 0 package(s) from C:\Users\foo\AppData\Local\vcpkg\archives in 161 us. Use --debug to see more details.
Installing 1/2 zlib:x64-windows...
Building zlib[core]:x64-windows...
-- Using cached madler-zlib-v1.2.13.tar.gz.

*** 途中省略 ***

-- Fixing pkgconfig file: C:/Users/foo/Documents/Github/vcpkg/packages/curl_x64-windows/debug/lib/pkgconfig/libcurl.pc
-- Installing: C:/Users/foo/Documents/Github/vcpkg/packages/curl_x64-windows/share/curl/vcpkg-cmake-wrapper.cmake
-- Installing: C:/Users/foo/Documents/Github/vcpkg/packages/curl_x64-windows/share/curl/copyright
-- Performing post-build validation
Stored binary cache: "C:\Users\foo\AppData\Local\vcpkg\archives\0b\0be4e066bb110c9e83d7ab0d78d61cee202eb0797b927e196b1af2e37d0a65d4.zip"
Elapsed time to handle curl:x64-windows: 1.262 min
Total install time: 1.423 min
curl provides CMake targets:

    # this is heuristically generated, and may not be correct
    find_package(CURL CONFIG REQUIRED)
    target_link_libraries(main PRIVATE CURL::libcurl)


C:\Users\foo\Documents\Github\vcpkg>

 

以上で libcurl のインストールを完了です。

 

(4) Visual Studio へ組み込む

vcpkg integrate install コマンドを実行することで、vcpkgでインストールしたライブラリを Visual Studio から利用できるようになります。インクルードディレクトリやライブラリディレクトリ、およびライブラリが自動で "Visual Studio" に追加されます。

Visual Studio 環境へ組み込まれることを好まない場合、こちらのコマンドを実行せずにご自身で個別にプロジェクトへ インクルードディレクトリやライブラリディレクトリ、およびライブラリの設定を行ってください。

vcpkg integrate install

[実行例]

C:\Users\foo\Documents\Github\vcpkg>vcpkg integrate install
Applied user-wide integration for this vcpkg root.
CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=C:/Users/foo/Documents/Github/vcpkg/scripts/buildsystems/vcpkg.cmake"

All MSBuild C++ projects can now #include any installed libraries. Linking will be handled automatically. Installing new libraries will make them instantly available.

C:\Users\foo\Documents\Github\vcpkg>

 

(5) インストールしたライブラリを確認

vcpkg list コマンドを実行することで、インストールしたライブラリ一覧を表示することができます。

vcpkg list

[実行例]

C:\Users\foo\Documents\Github\vcpkg>vcpkg list
curl:x64-windows                                  7.88.1              A library for transferring data with URLs
curl[non-http]:x64-windows                                            Enables protocols beyond HTTP/HTTPS/HTTP2
curl[schannel]:x64-windows                                            SSL support (Secure Channel)
curl[ssl]:x64-windows                                                 Default SSL backend
curl[sspi]:x64-windows                                                SSPI support
vcpkg-cmake-config:x64-windows                    2022-02-06#1
vcpkg-cmake:x64-windows                           2022-12-22
zlib:x64-windows                                  1.2.13              A compression library
zlib:x86-windows                                  1.2.13              A compression library

C:\Users\foo\Documents\Github\vcpkg>

 

 

3. i-PRO カメラと JPEG 接続して映像を表示してみる

[概要]

 c++(Visual Studio) と OpenCV, libcurl を使って、PC と i-PRO カメラを JPEG で接続して映像表示してみます。

 

[評価環境]

コンパイラ : Visual Studio 2022 pro., Version 17.5.1
ライブラリ : OpenCV, 4.6.0
  curl:x64-windows, 7.88.1
OS : Windows11 home, 22H2

 

※ "Community edition" でも動作する内容です。

 

 

[プログラム]

サンプルプログラムのソースコードを以下に示します。

 

[プログラムソース "connect_with_jpeg_1.cpp"]

/*
======================================================================================
[Abstract]
    Try connecting to an i-PRO camera with JPEG.
    HTTPで接続してJPEGの連続表示で i-PRO カメラと接続してみる

[Details]
    Let's try first.
    まずはやってみる

[Library install]
    opencv:     See "https://i-pro-corp.github.io/Programing-Items/cpp_vs/install_opencv.html"
    libcurl:    See "https://i-pro-corp.github.io/Programing-Items/cpp_vs/connect_camera/connect_with_jpeg.html"
======================================================================================
*/

#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
#include <opencv2/core/utility.hpp>
#include <curl/curl.h>


const std::string user_id       = "user-id";         // Change to match your camera setting
const std::string user_pw       = "password";        // Change to match your camera setting
const std::string host          = "192.168.0.10";    // Change to match your camera setting
const std::string resolution    = "1920";
const std::string winname       = "VIDEO";           // Window title
const std::string cameraURL     = "http://" + host + "/cgi-bin/camera?resolution=" + resolution;


/// <summary>
/// A curl callback function. Call this function when data is received.
/// </summary>
/// <param name="ptr">ptr points to the delivered data.</param>
/// <param name="size">size is always 1.</param>
/// <param name="nmemb">the size of the deliverd data is nmemb.</param>
/// <param name="userdata">Pointer to buffer specified by CURLOPT_WRITEDATA</param>
/// <returns>
/// Return the number of bytes actually taken care of.
/// If that amount differs from the amount passed to your callback function, it will signal an error condition to the library.
/// This will cause the transfer to get aborted and the libcurl function used will return CURLE_WRITE_ERROR.
/// </returns>
/// <detail>See "https://curl.se/libcurl/c/CURLOPT_WRITEFUNCTION.html" for details.</detail>
size_t onReceive(void* ptr, size_t size, size_t nmemb, void* userdata) {
    std::vector<char>* receiveBuffer = (std::vector<char>*)userdata;
    const size_t sizes = size * nmemb;

    receiveBuffer->insert(receiveBuffer->end(), (char*)ptr, (char*)ptr + sizes);

    return sizes;
}


/// <summary>
/// Receiving one JPEG image from the i-PRO camera.
/// </summary>
/// <param name="url">CGI command for 1 shot JPEG</param>
/// <param name="receiveBuffer">A variable to store the received JPEG image</param>
/// <retval>true: Success to get JPEG image.</retval>
/// <retval>false: Failed to get JPEG image.</retval>
bool get_jpeg_image(const std::string url, std::vector<char>& receiveBuffer) {
    CURL*       curl = NULL;
    CURLcode    res;

    // initialize curl.
    curl = curl_easy_init();
    if (!curl) {
        printf("curl_easy_init() failed...\n");
        return false;
    }

    // curl option for digest authentication
    curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
    std::string user_id_pw = user_id + ":" + user_pw;
    curl_easy_setopt(curl, CURLOPT_USERPWD, user_id_pw.c_str());

    // curl option
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &receiveBuffer);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onReceive);

    // execute
    res = curl_easy_perform(curl);

    if (res != CURLE_OK) {
        printf("curl_easy_perform() failed...%s\n", curl_easy_strerror(res));
        return false;
    }
    curl_easy_cleanup(curl);
    return true;
}


/// <summary>
/// main function
/// </summary>
/// <returns>Always returns EXIT_SUCCESS(0).</returns>
int main() {
    cv::Mat recv_data;
    bool isDataReceived;
    char ret;
    std::vector<char> receiveBuffer;

    while (true) {

        // get image data by HTTP
        isDataReceived = get_jpeg_image(cameraURL, receiveBuffer);
        if (!isDataReceived) {
            std::cout << "get_jpeg_image() failed..." << std::endl;
            break;
        }

        // JPEG decode
        cv::Mat frame = cv::imdecode(receiveBuffer, cv::IMREAD_UNCHANGED);

        // Clear all received data.
        receiveBuffer.clear();

        // Please modify the value to fit your PC screen size.
        resize(frame, frame, cv::Size(), 0.5, 0.5);                     // Setting by magnification.

        // Display video.
        cv::imshow(winname, frame);

        ret = (char)cv::waitKey(1);     // necessary to display the video by cv::imshow().

        // Press the "q" key to finish.
        if (ret == 'q') {
            break;
        }
    }

    cv::destroyAllWindows();

    return EXIT_SUCCESS;
}

 

上記プログラムを動かした様子を動画で示します。

こんなに簡単なプログラムでとても快適な映像表示を実現することができました。

[動画] JPEG でカメラと接続して映像表示した様子

 

 

ソースコード所在

本ページで紹介のソースコードは、下記 github より取得できます。

下記 github のソースコードと本ページの内容は差異がある場合があります。

i-pro-corp/cpp-examples: c++ sample programs for i-PRO camera. (github.com)

 

 

ライセンス

本ページの情報は、特記無い限り下記ライセンスで提供されます。


Copyright 2023 i-PRO Co., Ltd.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

 

 

参考

 


 

変更履歴

2023/10/20 - IP簡単設定ソフトウェア、IP Setting Software リンク先を更新, 木下英俊
2023/3/22 - 新規作成, 木下英俊

 

i-PRO - Programming Items トップページ

プライバシーポリシー