Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Efficient way to apply a minimum filter

Hi,

I am trying to implement a function which takes an image (type: CV_64FC3) and applies two operations on it:

  1. Each RGB pixel is replaced by the minimum channel value resulting in a CV_64C1 type image.
  2. A minimum filter of size blockSize is applied.

The function is performing as required but it takes approximately 1600ms to process a single image of resolution 720 x 576 with blockSize of 15. My question is whether I can do anything to make it computationally efficient, particularly for loop. Code:

Mat darkChannel(Mat im, int blockSize)
{
    int padSize = (blockSize - 1) / 2;
    double minVal;

    Mat temp, minChannel, borderMinChannel, bgr[3];

    split(im, bgr); //split into RGB channels
    (cv::min)(bgr[0], bgr[1], temp); //find minimum between R and G channels
    (cv::min)(temp, bgr[2], minChannel); 

    copyMakeBorder(minChannel, borderMinChannel, padSize, padSize, padSize, padSize, BORDER_REPLICATE); //padding

    Mat dc = Mat::zeros(borderMinChannel.rows, borderMinChannel.cols, CV_64FC1); //create Mat to store final result
    double* p;

    for (int i = padSize; i < borderMinChannel.rows - padSize; i++)
    {
        p = dc.ptr<double>(i);
        for (int j = padSize; j < borderMinChannel.cols - padSize; j++)
        {
            minMaxLoc(borderMinChannel(Rect(j - padSize, i - padSize, 2 * padSize + 1, 2 * padSize + 1)), &minVal, NULL); //find the minimum value in a block
            p[j] = minVal; //put the minimum value in Mat
        }
    }

    dc = dc(Rect(padSize, padSize, minChannel.cols, minChannel.rows)); //remove padding to return to original size
    return dc;
}

Efficient way to apply a minimum filter

Hi,

I am trying to implement a function which takes an image (type: CV_64FC3) and applies two operations on it:

  1. Each RGB pixel is replaced by the minimum channel value resulting in a CV_64C1 type image.
  2. A minimum filter of size blockSize is applied.

The function is performing as required but it takes approximately 1600ms to process a single image of resolution 720 x 576 with blockSize of 15. My question is whether I can do anything to make it computationally efficient, particularly for loop. Code:

Mat darkChannel(Mat im, int blockSize)
{
    int padSize = (blockSize - 1) / 2;
    double minVal;

    Mat temp, minChannel, borderMinChannel, bgr[3];

    split(im, bgr); //split into RGB channels
    (cv::min)(bgr[0], bgr[1], temp); //find minimum between R and G channels
    (cv::min)(temp, bgr[2], minChannel); 

    copyMakeBorder(minChannel, borderMinChannel, padSize, padSize, padSize, padSize, BORDER_REPLICATE); //padding

    Mat dc = Mat::zeros(borderMinChannel.rows, borderMinChannel.cols, CV_64FC1); //create Mat to store final result
    double* p;

    for (int i = padSize; i < borderMinChannel.rows - padSize; i++)
    {
        p = dc.ptr<double>(i);
        for (int j = padSize; j < borderMinChannel.cols - padSize; j++)
        {
            minMaxLoc(borderMinChannel(Rect(j - padSize, i - padSize, 2 * padSize + 1, 2 * padSize + 1)), &minVal, NULL); //find the minimum value in a block
            p[j] = minVal; //put the minimum value in Mat
        }
    }

    dc = dc(Rect(padSize, padSize, minChannel.cols, minChannel.rows)); //remove padding to return to original size
    return dc;
}