I tried sending and receiving images between the parent and child processes using normal pipe
s, using the OpenCV Mat
object.
The algorithm being used is:
1. Child reads an image
2. Stores it in a pipe
3. Signals the Parent that image has been written into pipe
4. Parent receives the signal and (in signal_handler
) reads the image from the pipe
and displays the image.
This is to be compiled as: $ g++ simple_pipe.cpp -o sp
pkg-config --cflags --libs opencv
The code goes by...
#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;
}
The problem I am facing is that the image obtained is corrupted - meaning, it's completely black
This is the original image being read
And, this is the black resulting image read by the parent:
I wanted to know where I am missing out on the reading/writing(or compressing) part so that I can read the same image on the parent side?