Why is opencv slower than Matlab in clustering?

asked 2018-06-04 02:56:42 -0500

Mehr gravatar image

updated 2018-06-12 09:56:52 -0500

Hi, I have some codes in Matlab and i want to speedup the code by reimplementing that in opencv and c++. I tested clustering one image of my video by kmeans and EM. I was surprised when the speed for kmeans in matlab was two times faster. I also tested the speed for EM. It took 5 seconds in Matlab while 100 seconds in opencv to cluster my image. Is that reasonable since i heard opencv c++ is much faster than matlab? My code to test EM speed in opencv is as follows. The sample also includes image pixels in three dimensional feature space. Is there any way to speedup the code?

int main() {
Mat frame = imread("frame.jpg");
Mat sample;
sample = frame.reshape(1, frame.rows*frame.cols);
sample.convertTo(sample, CV_32F);
Mat labels, centers;
clock_t init; init = clock();
Ptr<EM> em_model = EM::create();
em_model->setTermCriteria(TermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 300, 1)); 
em_model->trainEM(sample, noArray(), labels, noArray()); 
cout << "time:" << (double)(clock() - init) / ((double)CLOCKS_PER_SEC) << endl;
return 0;


edit retag flag offensive close merge delete


How do you create sample? What are it's type, rows, columns, and channels?

Tetragramm gravatar imageTetragramm ( 2018-06-04 21:50:14 -0500 )edit

My sample size is 3* 2088960. I joined three channels of my input image to create a sample size of 3*2088960, and 2088960 is the number of pixels in my image. it's type is also CV_32F.

Mehr gravatar imageMehr ( 2018-06-07 11:26:38 -0500 )edit

Just to be sure, is that 3 rows, or 3 columns? It ought to be 3 columns.

Tetragramm gravatar imageTetragramm ( 2018-06-07 17:01:17 -0500 )edit

yes it has three columns. The result is correct. It just took much time. I used similar sample in matlab. 146 seconds is really long for one frame of video.

Mehr gravatar imageMehr ( 2018-06-08 00:39:10 -0500 )edit

I dunno. I'm seeing a number about 3 seconds per cluster. I'm afraid I don't know any more. Nothing obvious in the code you've linked, I copied that to get the 3 seconds per cluster.

Tetragramm gravatar imageTetragramm ( 2018-06-08 15:42:22 -0500 )edit

Thanks for your reply. but it is really weird. what is your sample size? is this an easy image to cluster? my complete code has nothing special after removing other parts. It is as above.

Mehr gravatar imageMehr ( 2018-06-09 01:22:41 -0500 )edit

Can you share the frame.jpg? I ran the code using a randu(frame, 0, 255) and it took 8.3 seconds.

Tetragramm gravatar imageTetragramm ( 2018-06-10 15:26:23 -0500 )edit

I attached one frame of my video

Mehr gravatar imageMehr ( 2018-06-11 06:39:23 -0500 )edit

8.3 seconds again. Are you running in Debug instead of Release? That's 58 seconds for me, which is within the range of possibilities for different computers.

Tetragramm gravatar imageTetragramm ( 2018-06-11 18:32:06 -0500 )edit

Thanks for your comment. i was running it in debug mode. Then i changed it to release mode, but the running time has reduced less than 3 seconds. Why? is there any setting i do not know about? I am running matlab and c++ on the same laptop.

Mehr gravatar imageMehr ( 2018-06-12 09:58:26 -0500 )edit