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
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
#include
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;
}