rouge
rouge

Reputation: 437

Opencv slow code: Is something wrong?

here is a function where I try to improve the image colors. It works but it is really slow...Maybe someone has a better idea?

static Mat correctColor(Mat AImage) {
    Mat copyImage;
    AImage.copyTo(copyImage);
    Mat imgLab;
    cvtColor(copyImage, imgLab, CV_BGR2Lab);


    for (int y = 0; y < imgLab.rows; y++) {
        for (int x = 0; x < imgLab.cols; x++) {
            //get pixel value                
            imgLab.ptr<uchar > (y)[x * 3] = imgLab.ptr<uchar > (y)[x * 3]*0.3;
        }
    }
    cvtColor(imgLab, copyImage, CV_Lab2BGR);

    Mat img(copyImage.rows, copyImage.cols, CV_32FC3);
    copyImage.convertTo(img, CV_32FC3, 1 / 255.);        
    blur(img, img, Size(255, 255));
    Mat img32(copyImage.rows, copyImage.cols, CV_32FC3);
    copyImage.convertTo(img32, CV_32FC3, 1 / 255.);

    img.mul(img, 2);        
    divide(img32, img, img);

    img.convertTo(copyImage, CV_8U, 255.0);

    return copyImage;
 }

Upvotes: 2

Views: 2902

Answers (5)

Santhosh Nagasanthosh
Santhosh Nagasanthosh

Reputation: 23

Apart from the optimizations to the programs. You can add compiler optimization flags like -o3 and -NDEBUG, while compiling.

Upvotes: -2

Sam
Sam

Reputation: 20058

The best way to optimize is to start where you spend the most time. So, I strongly recommend you to profile this code to know exactly which parts of your code are the most time-consuming.

Now, some general ideas on how to improve:

  • If there is any chance to get rid of the convert to Lab, do it.
  • Do not use floats. There are a number of other ways to do math, without floating point. So, try first on uchars (get rid of the normalization step), then, if the approximation is too bad, convert to unsigned short, then back to uchar, when all the calculations are done.
  • Try to find another operation instead of divide. It is one of the most expensive math operations you can do on a computer. Maybe you can shift bits, or find an operation with a similar result.
  • Do not access elements by ptr. Search on SO for fast Mat access.
  • blur on a 255x255 window is a killer. I suspect it takes 95% of your processing time. You really cannot make it smaller? or use a box filter? or not use it at all? Or look on the internet for a FFT filter implementation. It is much faster than the simple window approach used by opencv.

Upvotes: 2

karlphillip
karlphillip

Reputation: 93410

The major problem is that you are creating several copies of the original image in memory: AImage, copyImage, imgLab, img, img32.

First optimization should be what @Eric suggested (pass by reference):

static Mat correctColor(Mat& AImage) {

As for the rest of your code, see if you can decrease the number of copies you work with.

OpenCV has a GPU module which implements several functions in the GPU, including cv::blur(). This implementation is based on the CUDA framework, so if your graphics card is NVIDIA you are in luck: gpu::blur().

Upvotes: 2

Federico Cristina
Federico Cristina

Reputation: 2223

Improve image colors? You should try Histogram Equalization instead. Look for the equalizeHist() function.

Upvotes: 0

Eric
Eric

Reputation: 2341

First of all, you should pass your argument by reference since you already create a clone in your code.

Upvotes: 1

Related Questions