Revision history [back]

Why is thresholding so slow?

I am creating a mask from an image with the size: 2000x640, and I'm running this code on a modern powerfull laptop.

I have made a function which is suppose to create binary mask from my input image, the code is quite simple and shown below:

However, when running the code it seems like doing a simple threshold takes a very long time - almost half a second.

ms_allocation: 0.001

ms_converted: 0.001

ms_thresholding: 0.383

ms_median_blur: 0.001

ms_locate_contour: 0.067

This looked very odd, so I implemented my own thresholding which ran in a few ms. However, not suddenly the median_blur became equally slow.

I then completely removed the thresholding part of the code and got this performance result

ms_allocation: 0.0008

ms_converted: 0.002

ms_thresholding: 0.000

ms_median_blur: 0.424

ms_locate_contour: 0.106

Can someone help me understand what is going on here? Why is the first call to openCV so slow, and can I prevent it somehow?

I would really prefer is this code could run in less than 0.1 s, which I think it totally reasonable.

void calculateMask(Mat & pSrc, Mat & pDst)
{

auto ms_alloc_start = getTickCount();

// Allocate, just to be sure it's done in advance.
Mat sharp = Mat::zeros(pSrc.size(), CV_8U);

auto ms_alloc_end = getTickCount();
auto ms_convert_start = getTickCount();

pSrc.convertTo(sharp, CV_8U);

auto ms_convert_end = getTickCount();
auto ms_threshold_start = getTickCount();

auto ms_threshold_end = getTickCount();
auto ms_median_start = getTickCount();

auto ms_median_end = getTickCount();
auto ms_copy_start = getTickCount();

auto ms_copy_end = getTickCount();

auto ms_find_contour_start = getTickCount();

auto ms_find_contour_end = getTickCount();

cout << "\n\n\tms_allocation: " << to_string((ms_alloc_end - ms_alloc_start) / getTickFrequency()) << "\n";
cout << "\tms_converted: " << to_string((ms_convert_end - ms_convert_start) / getTickFrequency()) << "\n";
cout << "\tms_thresholding: " << to_string((ms_threshold_end - ms_threshold_start)/ getTickFrequency()) << "\n";
cout << "\tms_median_blur: " << to_string((ms_median_end - ms_median_start) / getTickFrequency()) << "\n";
cout << "\tms_copy_mask: " << to_string((ms_copy_end - ms_copy_start) / getTickFrequency()) << "\n";
cout << "\tms_locate_contour: " << to_string((ms_find_contour_end - ms_find_contour_start) / getTickFrequency()) << "\n";
}


Why is thresholding the first openCV API call so slow?

I am creating a mask from an image with the size: 2000x640, and I'm running this code on a modern powerfull laptop.

I have made a function which is suppose to create binary mask from my input image, the code is quite simple and shown below:

However, when running the code it seems like doing a simple threshold takes a very long time - almost half a second.

ms_allocation: 0.001

ms_converted: 0.001

ms_thresholding: 0.383

ms_median_blur: 0.001

ms_locate_contour: 0.067

This looked very odd, so I implemented my own thresholding which ran in a few ms. However, not suddenly the median_blur became equally slow.

I then completely removed the thresholding part of the code and got this performance result

ms_allocation: 0.0008

ms_converted: 0.002

ms_thresholding: 0.000

ms_median_blur: 0.424

ms_locate_contour: 0.106

Can someone help me understand what is going on here? Why is the first call to openCV so slow, and can I prevent it somehow?

I would really prefer is this code could run in less than 0.1 s, which I think it totally reasonable.

void calculateMask(Mat & pSrc, Mat & pDst)
{

auto ms_alloc_start = getTickCount();

// Allocate, just to be sure it's done in advance.
Mat sharp = Mat::zeros(pSrc.size(), CV_8U);

auto ms_alloc_end = getTickCount();
auto ms_convert_start = getTickCount();

pSrc.convertTo(sharp, CV_8U);

auto ms_convert_end = getTickCount();
auto ms_threshold_start = getTickCount();

auto ms_threshold_end = getTickCount();
auto ms_median_start = getTickCount();

auto ms_median_end = getTickCount();
auto ms_copy_start = getTickCount();

auto ms_copy_end = getTickCount();

auto ms_find_contour_start = getTickCount();