2

I am working on an opencv application that is consumes CPU heavily.

I want to make the frame processing distributed so that it will be shared among many hosts.

The idea is the same as that implemented in http://cloudcv.org/. but the problem is that you can only send your request to their server to test distributed image processing.

I search for long time on internet, and I wonder if I can implement opencv + Docker Swarm, or opencv + Apache Spark or if there is some other method to make it distributed.

My code processes frames in opencv to detect people in them, I want to get it executed on many hosts to maximize speed:

while(true)
{
                       webcam.read(image);
                        //human detection--------------------------------------
                        cv::Mat resized_image;
                        cv::resize(image, resized_image, Size(image.cols / 2, image.rows / 2), 0, 0, INTER_LINEAR);
                        vector<Rect> found, found_filtered;
                        // this line uses hog descriptor to detect 
                        // people body pattern in the frmaes
                        // found is a vector of Rect that contains the 
                        // found peoples. 
                        // Rect is a struct (x, y, height, width)
                        hog.detectMultiScale(image, found, 0, Size(8, 8), Size(32, 32), 1.05, 2);
                        size_t u, h;
                        // this loop just make sure that the found
                        // rectangles are not duplicated.
                        for (u = 0; u<found.size(); u++)
                        {
                            Rect r = found[u];
                            for (h = 0; h<found.size(); h++)
                                if (h != u && (r & found[h]) == r)
                                    break;
                            if (h == found.size())
                                found_filtered.push_back(r);
                        }
                        // this loop is for drawing the rectangles on the frame
                        for (u = 0; u<found_filtered.size(); u++)
                        {
                            Rect r = found_filtered[u];
                            r.x += cvRound(r.width*0.1);
                            r.width = cvRound(r.width*0.8);
                            r.y += cvRound(r.height*0.07);
                            r.height = cvRound(r.height*0.8);
                            rectangle(showed_image, r.tl()*2, r.br()*2, Scalar(0, 255, 0), 3);
                            cout << '\a';
                        }
    }
ProEns08
  • 1,856
  • 2
  • 22
  • 38
  • 1
    If your algorithm is parallelizable, Apache Spark can probably offer you a solution. The question as it stands right now is too broad for this forum. To help you out, we need more information about the algorithm than what's provided at the moment. – maasg Apr 18 '16 at 11:27
  • @maasg: thank you. I like just to have a guiding instructions to do so. I searched a lot but I didnot find the method to do this. – ProEns08 Apr 18 '16 at 11:30
  • 1
    If you add the key elements of your process + code to the question I could try to map it out to a spark job, at least in some rough lines. – maasg Apr 18 '16 at 11:33
  • @maasg: I added the code related to my application. – ProEns08 Apr 18 '16 at 11:46
  • could you also add few comments about what each section intends to achieve? 1st loop finds images that do not fit this condition: `(r & found[h]) == r`. But that does that mean? I suppose that that O(n^2) iteration is what makes this algo heavy, no? – maasg Apr 18 '16 at 12:22
  • @maasg: thanks a lot for your support. I add some comments. what do you think about docker swarm. which is the best approach: using apache spark or docker swarm. I found this implementation of opencv on docker swarm. – ProEns08 Apr 18 '16 at 13:04
  • Do you intend to send each frame to a different processor, or split each frame across multiple processors? Have you considered MPI for distributing frames amongst processors? – Mark Setchell Apr 18 '16 at 14:51
  • @MarkSetchell: yes I want to share the execution on many hosts. even to divide the frame or to send every frame to a different processor. My goal is to make it distributed. But I don't know the easiest way. thanks. – ProEns08 Apr 18 '16 at 14:59
  • and do you want to distribute the process of a collection of images or of a single image? – maasg Apr 18 '16 at 19:03
  • @maasg: thanks. I want to process every frame in a separate host. how to do this? – ProEns08 Apr 18 '16 at 19:08
  • What is a frame in your definition? The result of `webcam.read(image);` ? step 1 will be to de-couple capture from processing – maasg Apr 18 '16 at 19:10
  • yes you are right. how to do so that every image to a separate host in spark? – ProEns08 Apr 18 '16 at 19:13
  • 1
    For a couple of other options, I demonstrate how to send an image to multiple hosts using MPI in my answer here http://stackoverflow.com/a/33307044/2836621 - of course you would send a different frame to each processing node. I also show how to put images into REDIS here http://stackoverflow.com/a/32268028/2836621 and have multiple CPUs pop frames and process them. – Mark Setchell Apr 18 '16 at 20:45
  • @MarkSetchell: thanks a lot, +1 for the two clear answers. But I don't exactly what is redis? – ProEns08 Apr 18 '16 at 21:15
  • It would be great thing, if someone know how to process frames on separate processes using apache-spark. – ProEns08 Apr 18 '16 at 21:31

1 Answers1

3

Spark is a great way of doing processing on distributed systems. But it doesn't have a strong community working on OpenCV. Storm is another Apache's free and open source distributed realtime computation system. Storm makes it easy to reliably process unbounded streams of data, doing for realtime processing what Hadoop did for batch processing.

StormCV is an extension of Apache Storm specifically designed to support the development of distributed computer-vision pipelines. StormCV enables the use of Storm for video processing by adding computer vision (CV) specific operations and data model. The platform uses OpenCV for most of its CV operations and it is relatively easy to use this library for other functions.

There are a few examples of using storm with OpenCV. There is a similar example of what you are trying on their official github page. You might want to look at this face detection example and try it to do human detection - https://github.com/sensorstorm/StormCV/blob/master/stormcv-examples/src/nl/tno/stormcv/example/E2_FacedetectionTopology.java.

Tejus Prasad
  • 6,322
  • 7
  • 47
  • 75
  • Thanks, +1. But the problem is that StormCV uses the java API. My code is purely C++ because it is more efficient in term of processing. – ProEns08 Jul 14 '16 at 05:12
  • 1
    I have also been working on running OpenCV through Spark in my research. Hopefully if i can great performance i can send you the link to my github code. – Tejus Prasad Jul 15 '16 at 23:26
  • @TejusPrasad have you been able to get spark+opencv to work ? im exploring which approach to take here – Sandeep Jul 25 '17 at 11:56