Правильный метод отправки и чтения данных объекта OpenCV Mat между процессами через каналы - PullRequest
1 голос
/ 30 января 2020

Я попытался отправить и получить изображения между родительским и дочерним процессами, используя обычные pipe s, используя объект OpenCV Mat.

Используемый алгоритм:
1. Ребенок читает image
2. Сохраняет его в pipe
3. Сигнализирует Родителю, что изображение было записано в pipe
4. Родитель получает сигнал и (в signal_handler) считывает изображение с pipe и отображает изображение.

Это должно быть скомпилировано как:
$ g++ simple_pipe.cpp -o sp pkg-config --cflags --libs opencv

Код идет по ...

#include <bits/stdc++.h>
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h>

// OpenCV 3.4 libraries
#include <opencv2/opencv.hpp>   // FOR OpenCV
#include <opencv2/core.hpp>     // Basic OpenCV structures (cv::Mat)
#include <opencv2/videoio.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>



// #defines...
#define IMG_HT 180      // == ROWS 
#define IMG_WD 180      // == COLS
#define BUFF_SIZE (3*IMG_HT*IMG_WD)
#define BFSZ 1024
#define SLEEP_FOR_SOME_TIME 10

using namespace std;

int fd1[2], fd2[2];
// fd1 => for parent ; 0 - read, 1 - write
// fd2 => for child ; 0 - read, 1 - write

pid_t child_pid;

void signal_handler(int signal_number) {

    if (child_pid == 0) {
        // the child part
    }
    else {
        // the parent part
        printf("Signalled, with signum = %d, and PID = %d\n", signal_number, getpid());
        // close unwanted ends
        close(fd1[1]);
        close(fd2[1]);
        close(fd1[0]);

        unsigned char buffer[BUFF_SIZE];
        read(fd2[0], buffer, BUFF_SIZE);
        close(fd2[0]);

        for (int i=0; i<100; i++) {
            printf("%u ", buffer[i]);
        }
        cout << "\n";

        cv::Mat img(IMG_HT, IMG_WD, CV_8UC3, cv::Scalar(0, 0, 0));
        img.data = (buffer);

        pid_t theProcess = getpid();
        string windowName = to_string(theProcess);

        cv::imshow(windowName, img);
        cv::waitKey(0); 
    }

}



int main() {

    int res1 = pipe(fd1);
    int res2 = pipe(fd2);

    if (res1 == -1 or res2 == -1) {
        printf("Pipe failed!\n");
        exit(EXIT_FAILURE);
    }

    signal(SIGABRT, signal_handler);

    child_pid = fork();

    if (child_pid < 0) {
        printf("Fork failed!\n");
        exit(EXIT_FAILURE);
    }

    if (child_pid == 0) {
        // child part
        printf("This is the child, with PID = %d, and parent PID = %d\n", getpid(), getppid());
        char *imgName = "Dbo2.jpg";
        // open image
        cv::Mat img = cv::imread(imgName);
        // cv::resize(img, img, cv::Size(IMG_WD, IMG_HT));

        // close unwanted ends
        close(fd1[1]);
        close(fd1[0]);
        close(fd2[0]);

        write(fd2[1], img.data, sizeof(img.data));
        close(fd2[1]);

        kill(getppid(), SIGABRT);

        while (1) {
            sleep(SLEEP_FOR_SOME_TIME);
        }
    }
    else {
        // parent part
        printf("The parent PID is: %d, with child PID = %d\n", getpid(), child_pid);
        while (1) {
            sleep(SLEEP_FOR_SOME_TIME);
        }
    }


    return 0;
}

Проблема, с которой я сталкиваюсь, заключается в том, что полученное изображение повреждено - то есть оно полностью черное

Это исходное изображение, которое читается
wormhole.jpg И это черное результирующее изображение, читаемое родителем:
result

Я хотел знать, где я пропускаю часть чтения / записи (или сжатия), так что я могу прочитать одно и то же изображение на родительской стороне?

...