DanBrezeanu
DanBrezeanu

Reputation: 552

Pipe image from python to C++ and back

I need to read an image (with OpenCV) in Python, pipe it to a C++ program and then pipe it back to Python. This is my code so far:

C++

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cv.h>
#include <highgui.h>
#include <cstdio>

#include <sys/stat.h>

using namespace std;
using namespace cv;

int main(int argc, char *argv[]) {
    const char *fifo_name = "fifo";
    mknod(fifo_name, S_IFIFO | 0666, 0);
    ifstream f(fifo_name);
    string line;
    getline(f, line);
    auto data_size = stoi(line);

    char *buf = new char[data_size];
    f.read(buf, data_size);

    Mat matimg;
    matimg = imdecode(Mat(1, data_size, CV_8UC1, buf), CV_LOAD_IMAGE_UNCHANGED);

    imshow("display", matimg);
    waitKey(0);

    return 0;
}

Python

import os
import cv2

fifo_name = 'fifo'

def main():
    data = cv2.imread('testimage.jpg').tobytes()
    try:
        os.mkfifo(fifo_name)
    except FileExistsError:
        pass
    with open(fifo_name, 'wb') as f:
        f.write('{}\n'.format(len(data)).encode())
        f.write(data)

if __name__ == '__main__':
    main()

An exception is thrown when C++ tries to print to image. I have debugged the code and buf is filled, but matimg is empty.

Upvotes: 1

Views: 653

Answers (1)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136515

In the code, the C++ reader calls mknod, whereas it should just open an existing named pipe created by the Python writer.

If the pipe doesn't exists when the reader tries to open it, it can either fail or keep re-trying to open the named pipe with a timeout. E.g.:

const char *fifo_name = "fifo";
std::ifstream f;
for(;;) { // Wait till the named pipe is available.
    f.open(fifo_name, std::ios_base::in);
    if(f.is_open())
        break;
    std::this_thread::sleep_for(std::chrono::seconds(3));
}

Upvotes: 1

Related Questions