图像降噪------LLSURE

代码如下:

void Denoise_LLSURE(cv::Mat &image, int radius, float sigma) {
    int width = image.cols, height = image.rows;
    cv::Mat I1, I2;
    cv::integral(image, I1, I2, CV_64FC1, CV_64FC1);
    I1 = I1(cv::Rect(1, 1, width, height));
    I2 = I2(cv::Rect(1, 1, width, height));
    cv::Mat varInv = cv::Mat::zeros(height, width, CV_64FC1);
    cv::Mat AMat = cv::Mat::zeros(height, width, CV_64FC1);
    cv::Mat BMat = cv::Mat::zeros(height, width, CV_64FC1);
    double epsilon = 1e-6f, sigma2 = sigma * sigma;
    for (int i = 0; i < height; ++i) {
        auto aData = AMat.ptr(i);
        auto bData = BMat.ptr(i);
        auto varDataInv = varInv.ptr(i);
        int yStart = std::max(i - radius, 0);
        int yEnd = std::min(i + radius, height - 1);
        auto IDataStart1 = I1.ptr(yStart);
        auto IDataStart2 = I2.ptr(yStart);
        auto IDataEnd1 = I1.ptr(yEnd);
        auto IDataEnd2 = I2.ptr(yEnd);
        int yLen = yEnd - yStart + 1;
        for (int j = 0; j < width; ++j) {
            int xStart = std::max(j - radius, 0);
            int xEnd = std::min(j + radius, width - 1);
            int xLen = xEnd - xStart + 1;
            double invNum = 1.0f / (yLen * xLen);
            double mean = (IDataEnd1[xEnd] - IDataEnd1[xStart] + IDataStart1[xStart] - IDataStart1[xEnd]) * invNum;
            double mean2 = (IDataEnd2[xEnd] - IDataEnd2[xStart] + IDataStart2[xStart] - IDataStart2[xEnd]) * invNum;
            double var = mean2 - mean * mean + epsilon;
            double invVar = 1.0 / (var);
            varDataInv[j] = invVar;
            double a = std::max(var - sigma2, 0.0) * invVar;
            double b = (1.0 - a) * mean;
            aData[j] = invVar * a;
            bData[j] = invVar * b;
        }
    }

    cv::Mat AIntegral, BIntegral, varInv_integral;
    cv::integral(AMat, AIntegral, CV_64FC1);
    AIntegral = AIntegral(cv::Rect(1, 1, width, height));
    cv::integral(BMat, BIntegral, CV_64FC1);
    BIntegral = BIntegral(cv::Rect(1, 1, width, height));
    cv::integral(varInv, varInv_integral, CV_64FC1);
    varInv_integral = varInv_integral(cv::Rect(1, 1, width, height));

    for (int i = 0; i < height; ++i) {
        int yStart = std::max(i - radius, 0);
        int yEnd = std::min(i + radius, height - 1);
        auto IDataStart1 = AIntegral.ptr(yStart);
        auto IDataStart2 = BIntegral.ptr(yStart);
        auto IDataEnd1 = AIntegral.ptr(yEnd);
        auto IDataEnd2 = BIntegral.ptr(yEnd);
        auto IDataStartInv = varInv_integral.ptr(yStart);
        auto IDataEndInv = varInv_integral.ptr(yEnd);
        auto imageData = image.ptr(i);
        //auto aData = AMat.ptr(i);
        //auto bData = BMat.ptr(i);
        for (int j = 0; j < width; ++j) {
            int xStart = std::max(j - radius, 0);
            int xEnd = std::min(j + radius, width - 1);
            double mean = (IDataEnd1[xEnd] - IDataEnd1[xStart] + IDataStart1[xStart] - IDataStart1[xEnd]);
            double mean2 = (IDataEnd2[xEnd] - IDataEnd2[xStart] + IDataStart2[xStart] - IDataStart2[xEnd]);
            double sumW = (IDataEndInv[xEnd] - IDataEndInv[xStart] + IDataStartInv[xStart] - IDataStartInv[xEnd]);
            double a = mean / sumW;
            double b = mean2 / sumW;
            imageData[j] = cv::saturate_cast(a * imageData[j] + b);
            //aData[j] = a;
            //bData[j] = b;
        }
    }
}

 

你可能感兴趣的:(图像增强,opencv,图像处理)