C++でカメラ画像取得をでマルチスレッドやってみる:Mutex版


概要

OpenCVを用いて、USBカメラから取得した画像を出力するプログラムを2つのスレッドで実行してみました。USBカメラは1つとして、2つのスレッドで画像取得、2つのスレッドで画像出力を行います。排他処理は、std::mutexを使用しました。結果としては、描画出力の更新速度がかなり遅かったです。

実行環境

次に実行環境を示します。

Soft and Hard バージョン
Visual Studio 2017
OpneCV 4.0.0

実装したプログラム

次に作成したマーカID取得プログラムを示します。カメラはUSBカメラを使いました。

multi_thread_with_mutex.cpp
#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"
#include<thread>
#include<time.h>
#include<mutex>

cv::VideoCapture cap(1);
cv::Mat frame;
std::mutex mtx;


void GetFrameFromCameraFunction() {

    while (true) {
        std::lock_guard<std::mutex> lock(mtx);
        printf("\nRead Thread\n");
        cap.read(frame);
    }
}

int ShowFrameFromCameraFunction() {

    while (true) {
        std::lock_guard<std::mutex> lock(mtx);
        printf("\nShow Thread\n");
        cv::imshow("WIndow1", frame);
        const int key = cv::waitKey(1);
        if (key == 27) {

            printf("\n Close Window !!\n");
            return 1;
        }
        else if (key == 's') {

            cv::imwrite("th2.png", frame);

        }
    }   
}


int main(int argh, char* argv[])
{

    std::thread GetFrameThread(GetFrameFromCameraFunction);
    std::thread ShowFrameThread(ShowFrameFromCameraFunction);

    ShowFrameThread.join();
    GetFrameThread.join();


    cv::destroyAllWindows();
    return 0;

}

実装プログラム実行

上記のプログラムを実行した場合の結果を示します。

  • 全体画像

描画更新速度がかなり遅いようです。次は、セマフォのような排他制御によってプログラムを実装してみたいと思います。

まとめ

1つのUSBカメラから単純に画像を2つのスレッドで分ける場合において、std::mutexを使用した場合には、描画更新速度がかなり遅いことがわかりました。また、間違っているところや、追加したほうがいい、こういう書き方の方がいいよ!という箇所がありましたら、お教え頂けるととても嬉しいです。