Speeding up pixelwise operations
I would like to compute an average LoG (Laplacian of Gauss) score over a given AOI. The problem, with the naive approach is, that it takes a really long time, and i have a stong feeling that it may have been done faster.
cv::Mat src = cv::Mat( imgSize.height(), imgSize.width(), CV_8UC4, (void*)imgPtr, (size_t)pitch );
cv::Mat roi;
if( subROI.isNull() ) {
roi = src;
} else {
cv::Rect rect = cv::Rect( subROI.x(), subROI.y(), subROI.width(), subROI.height() );
roi = src(rect);
}
cv::Mat grey;
cv::cvtColor(roi, grey, cv::COLOR_RGB2GRAY);
cv::GaussianBlur(grey, grey, cv::Size(3, 3), 0, 0, cv::BORDER_DEFAULT);
cv::Mat laplaced;
cv::Laplacian(grey, laplaced, CV_16S, 3, 1, 0, cv::BORDER_DEFAULT);
cv::convertScaleAbs(laplaced, laplaced);
float avg = 0.0;
for (int i = 0; i < laplaced.rows; i++)
{
for (int j = 0; j < laplaced.cols; j++)
{
avg += (float)laplaced.at<unsigned char>(i, j);
}
}
avg /= laplaced.rows*laplaced.cols;
return avg;
Any tip, to make the code run faster? (gonna run on mobile ivy bridge CPU)
you can replace the avg i,j loops by mean(), but i bet, most of the time spent is in GaussianBlur() and Laplacian()
don't 'feel', profile it:
uint64 t0 = cv::getTickCount();
// some operation
uint64 t1 = cv::getTickCount();
cerr << "operation took : " << ((t1-t0)/cv::getTickFrequency()) << " sec." << endl
Even better, use a profiler tool like valgrind to really look into what is taking the longest time! It will also show you where memory leaks are happening and such. Besides that you could try the GPU and OpenCL implementations to speed things up? Also running over Mat elements by row and column seems the dumb approach, look here on how to loop efficiently.