物理の駅 Physics station by 現役研究者

テクノロジーは共有されてこそ栄える

PocoとOpenCV: 共有メモリを使ってプロセス間で画像を送受信する

PocoとOpenCVによる画像の共有メモリ経由での書き込み・読み出しの実装例

画像を共有メモリから読み出す

OpenCVには、画像の先頭のポインタ sm.begin() を与えると自動的に画像として読んでくれるコンストラクタがあるので、それを利用した。 書き込む方と同じように memcpy を使っても良い。

#include <opencv2/opencv.hpp>
#include <Poco/SharedMemory.h>
#include <thread>
#include <chrono>

void main() {
    int width = 1024; //メモリのアライメントの都合で8の倍数にする
    int height = 600;
    size_t size = width * height;
    auto sm = Poco::SharedMemory("sharedmemory_test", size, Poco::SharedMemory::AccessMode::AM_WRITE);

    cv::Mat src;
    for (int i = 0; i < 100; i++) {
                //widthとheight、typeは事前に知っておく必要がある
        src = cv::Mat(cv::Size(width, height), CV_8UC1, sm.begin());
        cv::imshow("test", src);
        cv::waitKey(1000);
    }
}

画像を共有メモリに書き込む

1秒毎に画像を変えるために文字(数字)を書き込んでいる

#include <opencv2/opencv.hpp>
#include <Poco/SharedMemory.h>
#include <thread>
#include <chrono>

void main() {
    int width = 1024; //メモリのアライメントの都合で8の倍数にする
    int height = 600;
    size_t size = width * height;
    auto sm = Poco::SharedMemory("sharedmemory_test", size, Poco::SharedMemory::AccessMode::AM_WRITE);
    cv::Mat src = cv::Mat::zeros(cv::Size(width, height), CV_8UC1); //白黒画像

    for (int i = 0; i < 100; i++) {
        src = cv::Scalar(0);
        cv::putText(src, std::to_string(i), cv::Point(width / 2, height / 2), FONT_HERSHEY_SIMPLEX, 10, Scalar(255), 2, CV_AA);
        memcpy(sm.begin(), (void*)src.data, size); //共有メモリに画像を書き込む
        std::cout << i << " ";
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
    std::cout << std::endl;
}

送受信される画像の例

f:id:onsanai:20200924172437p:plain

セブン!