Segmentation Fault while using MPI and OpenCV together

前端 未结 3 531
死守一世寂寞
死守一世寂寞 2021-01-27 02:51

I am trying to learn MPI in C++. I have some knowledge of OpenCV so I tried writing a program using both MPI and OpenCV. This may sound stupid but for the purpose of learning I

相关标签:
3条回答
  • 2021-01-27 03:44

    Currently each process tries to open the camera. That is very likely to cause problems. Try to move the opening into the root specific section like so:

    int main(int argc, char **argv) {
      cv::Mat_<uint> img(640,480);
      cv::Mat_<uint> gray(640,480);
      cv::VideoCapture cam;
    
      /* ... */
      if (rank == 0) {
        cam.open(0);
        /* ... */
      }
      /* ... */
    }
    

    Update:

    I think the problem with your code is, that you can't simply transfer objects with MPI_Send. Also is the sizeof operator not valid on objects in general. If you want to transfer an object, you need to transfer the underlying data.

    You could achieve this in your case by sending img.data with a size of img.rows * img.cols * sizeof(uint). Then you can also use MPI_BYTE as data type and no custom types are required.

    Some details about the internal structure of cv::Mat_ can be found here.

    0 讨论(0)
  • 2021-01-27 03:44

    As noticed by @user0851 , in your code, all processes try to open the camera and the opening of the camera can be perform by the root process alone.

    The Mat object of openCV is quite complex and defining the corresponding MPI_Datatype may be complex too. Instead, sending the array of pixels img.data is much easier. Here is a little piece of code demonstrating how it could be done. It is compiled by mpiCC main.cpp -o main -lopencv_highgui -lopencv_imgproc -lopencv_core and run by mpirun -np 2 main

    #include <opencv2/opencv.hpp>
    #include <mpi.h>
    
    using namespace cv;
    
    int main(int argc, char **argv) {
        Mat img;
        Mat gray;
    
    
        int rank, nproc, j=0;
    
        size_t total;
        size_t elemsize;
        int sizes[3];
    
        MPI_Status status;
    
        MPI_Init(&argc, &argv);
    
        MPI_Comm_size(MPI_COMM_WORLD, &nproc); // number of processes
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);  // rank of the current process
    
        /*
         * Thread 0 captures the image from camera
         * and sends the image to process 1 for processing
         * thread 1 converts the image to grayscale and
         * displays the image
         */
    
        if (rank == 0) {
            VideoCapture cam(0);
            if(!cam.isOpened()){
                fprintf(stderr,"unable to open camera.\n");
                exit(1);
            }
            // capture the image and send to thread 1
            while (1) { 
                cam >> img;
                cv::imshow("proc 0", img);
    
                if(j==0){
                    sizes[2]=img.elemSize();
                    Size s = img.size();
                    sizes[0] = s.height;
                    sizes[1] = s.width;
                    MPI_Send( sizes, 3, MPI_INT, 1,0,   MPI_COMM_WORLD);
                }
                MPI_Send( img.data, sizes[0]*sizes[1]*3, MPI_CHAR,1,1, MPI_COMM_WORLD);
                cv::waitKey(40);
                j++;
            }
        }
        else if (rank == 1) {
            // receive the image, convert to grayscale and display
            while (1) {
                if(j==0){
                    MPI_Recv( sizes,3, MPI_INT,0,0, MPI_COMM_WORLD,&status);
                    img.create(sizes[0],sizes[1],CV_8UC3);
                }
                MPI_Recv( img.data, sizes[0]*sizes[1]*3, MPI_CHAR,0,1, MPI_COMM_WORLD,&status);
                cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
                cv::imshow("proc 1", gray);
                cv::waitKey(20);
                j++;
            }
        }
    
        MPI_Finalize();
    
        return 0;
    }
    
    0 讨论(0)
  • 2021-01-27 03:49

    Mat object is only a header structure that points to the memory that stores the image. So you have some problems: First, you create a Mat object sized 640X640 and than you read from the camera into that object. But Mat is just a header it is not a pointer to the data, The Mat object can be now of any width and height.

    Second, sizeof(Mat) does not return the amount of memory allocated to the image, only the amount of memory the Mat object itself. The amount of memory needed for the image is Mat.total()*Mat.elemSize()

    0 讨论(0)
提交回复
热议问题