OpenCV vs Matlab执行和优化的时间

时间:2015-01-25 15:13:50

标签: c++ performance matlab opencv image-processing

我将实施一篇论文中提出的均等化。 该方法包括用公式替换每个通道的每个值 在本演讲的第16张幻灯片中slides 首先,我在Matlab中以两种方式实现了这种均衡功能:在第一种方法中我计算每个通道的直方图(计数)以便知道 值的数量小于[0 255]范围内的特定值。或者,在第二种方式中,我使用一些矩阵运算(R <=值... G <=值.... V <=值)。 最初,我认为第二种方法在执行时间方面是最好的,但似乎并非......而且我第一次感到惊讶。

然后我在OpenCV中实现了这个功能,现在我感到很惊讶因为Matlab中的执行比C ++快!使用Matlab我有这些计时器值

Matlab,方法1:1,36秒

Matlab,方法2:1,74秒

在使用OpenCV的C ++中,我发现了以下值: OpenCV,方法1:2380毫秒 OpenCV,方法2:4651毫秒

我获得了相同的结果,所以函数是正确的,但我认为由于我在OpenCV方面的经验不足,可能会因为计算时间而出现问题,因为我希望编译的C ++函数比Matlab更快!! ....所以我的问题是如何优化C ++代码。在下面我使用两种方法放置C ++代码

//I have an RGB image in the Mat 'image'

    Mat channel[3];

    // Splitting method 1
    split(image, channel);
    Mat Red, Green, Blue;
    Blue = channel[0];
    Green = channel[1];
    Red = channel[2];

    //Splitting method 2
    // Separate the image in 3 places ( B, G and R )
//  vector<Mat> bgr_planes;
//  split(image, bgr_planes);

    double maxB, maxG, maxR, Npx;
    double min;
    double coeffB, coeffG, coeffR;
    Mat newB, newG, newR;
    Mat mapB, mapG, mapR;
    int P_Bi, P_Gi, P_Ri;
    Mat rangeValues;
    double intpart;
    double TIME;

    int histSize = 256;

    /// Set the ranges ( for B,G,R) )
    float range[] = { 0, 256 };
    const float* histRange = { range };

    bool uniform = true; bool accumulate = false;

    Mat countB, countG, countR;

    //Start the timer for the method 1
    TIME = (double)getTickCount();
    // Compute the histograms
    calcHist(&Blue, 1, 0, Mat(), countB, 1, &histSize, &histRange, uniform, accumulate);
    calcHist(&Green, 1, 0, Mat(), countG, 1, &histSize, &histRange, uniform, accumulate);
    calcHist(&Red, 1, 0, Mat(), countR, 1, &histSize, &histRange, uniform, accumulate);

    // Get the max from each channel
    minMaxLoc(Blue, &min, &maxB);
    minMaxLoc(Green, &min, &maxG);
    minMaxLoc(Red, &min, &maxR);

    //Number of pixels
    Npx = Blue.rows * Blue.cols;

    // Compute the coefficient of the formula
    coeffB = maxB / Npx;
    coeffG = maxG / Npx;
    coeffR = maxR / Npx;

    //Initialize the new channels
    newB = Mat(Blue.rows, Blue.cols, Blue.type(), cvScalar(0));
    newG = Mat(Green.rows, Green.cols, Green.type(), cvScalar(0));
    newR = Mat(Red.rows, Red.cols, Red.type(), cvScalar(0));

    //For each value of the range
    for (int value = 0; value < 255; value++)
    {
        mapB = (Blue == value)/255;
        mapG = (Green == value)/255;
        mapR = (Red == value)/255;

        //Number of pixels less or equal then 'value'
        rangeValues = countB(Range(0, value+1), Range(0, 1));
        P_Bi = cv::sum(rangeValues)[0];

        rangeValues = countG(Range(0, value + 1), Range(0, 1));
        P_Gi = cv::sum(rangeValues)[0];

        rangeValues = countR(Range(0, value + 1), Range(0, 1));
        P_Ri = cv::sum(rangeValues)[0];

        //Substitution of the value in the new channel plane
        modf((coeffB * P_Bi), &intpart);
        newB = newB + mapB * intpart;

        modf((coeffG * P_Gi), &intpart);
        newG = newG + mapG * intpart;

        modf((coeffR * P_Ri), &intpart);
        newR = newR + mapR * intpart;
    }


    TIME = 1000 * ((double)getTickCount() - TIME) / getTickFrequency();
    cout << "Method 1 - elapsed time: " << TIME << "milliseconds." << endl;

    //Here it takes 2380 milliseconds
    //....
    //....
    //....

    //Start timer of method 2
    TIME = 0;
    TIME = (double)getTickCount();

    //Get the max
    minMaxLoc(Blue, &min, &maxB);
    minMaxLoc(Green, &min, &maxG);
    minMaxLoc(Red, &min, &maxR);

    Npx = Blue.rows * Blue.cols;

    coeffB = maxB / Npx;
    coeffG = maxG / Npx;
    coeffR = maxR / Npx;

    newB = Mat(Blue.rows, Blue.cols, Blue.type(), cvScalar(0));
    newG = Mat(Green.rows, Green.cols, Green.type(), cvScalar(0));
    newR = Mat(Red.rows, Red.cols, Red.type(), cvScalar(0));

    Mat mask = cvCreateImage(Blue.size(), IPL_DEPTH_8U, 1);

    for (int value = 0; value < 255; value++)
    {

        mapB = (Blue == value) / 255;
        mapG = (Green == value) / 255;
        mapR = (Red == value) / 255;

        //Instead, there i used matrices operations
        mask = (Blue <= value)/255;
        P_Bi = cv::sum(mask)[0];

        mask = (Green <= value) / 255;
        P_Gi = cv::sum(mask)[0];

        mask = (Red <= value) / 255;
        P_Ri = cv::sum(mask)[0];


        modf((coeffB * P_Bi), &intpart);
        newB = newB + mapB * intpart;

        modf((coeffG * P_Gi), &intpart);
        newG = newG + mapG * intpart;

        modf((coeffR * P_Ri), &intpart);
        newR = newR + mapR * intpart;
    }

    //End of the timer
    TIME = 1000 * ((double)getTickCount() - TIME) / getTickFrequency();
    cout << "Method 2 - elapsed time: " << TIME << "milliseconds." << endl;
    //Here it takes 4651 milliseconds

0 个答案:

没有答案