CV

维纳滤波还原运动模糊图像

图像还原

Posted by bbkgl on November 3, 2019

一生思破红尘路

剑藏庐轩隐迷踪

前处理

通过双边滤波去除高斯噪声。

使用opencv实现:

cv:: bilateralFilter(src_img, temp, 25, 25 * 2, 25 / 2);

自适应维纳滤波

通过自适应维纳滤波处理运动模糊。

维纳滤波实现代码如下(opencv):

double WienerFilterImpl(const cv::Mat &src, cv::Mat &dst, double noiseVariance, const cv::Size &block) {

    assert(("Invalid block dimensions", block.width % 2 == 1 && block.height % 2 == 1 && block.width > 1 &&
                                        block.height > 1));
    assert(("src and dst must be one channel grayscale images", src.channels() == 1, dst.channels() == 1));

    int h = src.rows;
    int w = src.cols;

    dst = cv::Mat1b(h, w);

    cv::Mat1d means, sqrMeans, variances;
    cv::Mat1d avgVarianceMat;

    cv::boxFilter(src, means, CV_64F, block, cv::Point(-1, -1), true, cv::BORDER_REPLICATE);
    cv::sqrBoxFilter(src, sqrMeans, CV_64F, block, cv::Point(-1, -1), true, cv::BORDER_REPLICATE);

    cv::Mat1d means2 = means.mul(means);
    variances = sqrMeans - (means.mul(means));

    if (noiseVariance < 0) {
        cv::reduce(variances, avgVarianceMat, 1, CV_REDUCE_SUM, -1);
        cv::reduce(avgVarianceMat, avgVarianceMat, 0, CV_REDUCE_SUM, -1);
        noiseVariance = avgVarianceMat(0, 0) / (h * w);
    }

    for (int r = 0; r < h; ++r) {
        uchar const *const srcRow = src.ptr<uchar>(r);
        uchar *const dstRow = dst.ptr<uchar>(r);
        double *const varRow = variances.ptr<double>(r);
        double *const meanRow = means.ptr<double>(r);
        for (int c = 0; c < w; ++c) {
            dstRow[c] = cv::saturate_cast<uchar>(
                    meanRow[c] +
                    std::max(0., varRow[c] - noiseVariance) / std::max(varRow[c], noiseVariance) *
                    (srcRow[c] - meanRow[c])
            );
        }
    }

    return noiseVariance;
}

void WienerFilter(const cv::Mat &src, cv::Mat &dst, double noiseVariance = 10000, const cv::Size &block = cv::Size(3, 3)) {
    WienerFilterImpl(src, dst, noiseVariance, block);
    return ;
}

效果展示

处理前:

Hf581eb1cafb7415183808a56fba7c2b62

处理后:

H8d970c9e499748b3b93c3fe4f2d08196f