OpenCV计算摄影学(2)图像去噪函数denoise_TVL1()

  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

算法描述

原始-对偶算法是用于解决特定类型变分问题(即,寻找一个函数以最小化某个泛函)的算法。特别地,图像去噪可以被视为一种变分问题,因此可以使用原始-对偶算法来进行去噪,这正是这里实现的内容。

需要注意的是,此实现取自2013年7月的一篇博客文章[194],该文章还包含了(稍微更通用的)现成的Python源代码。随后,Vadim Pisarevsky在2013年7月底用C++和OpenCV重写了这段代码,并最终由后续作者对其进行了轻微调整。

尽管可以在[49]中找到对该算法的详细讨论和理论依据,但在这里根据[194]简要概述一下是有意义的。首先,我们将1字节灰度级图像视为从像素矩形域(可以看作是集合{(x,y)∈N×N∣1≤x≤n,1≤y≤m},对于某些m,n∈N)到{0,1,…,255}的函数。我们将噪声图像表示为fi,并且在这种视角下,给定相同大小的图像x,我们可以通过以下公式衡量它的“坏程度”: ∥ ∥ ∇ x ∥ ∥ + λ ∑ i ∥ ∥ x − f i ∥ ∥ \left\|\left\|\nabla x\right\|\right\| + \lambda\sum_i\left\|\left\|x-f_i\right\|\right\| x+λixfi 这里的 ∥ ∥ ⋅ ∥ ∥ \|\|\cdot\|\| ∥∥∥∥
表示L2范数,如你所见,第一个加项表明我们希望我们的图像尽可能平滑(理想情况下,梯度为零,从而保持常数),第二个加项则表明我们希望结果接近我们得到的观测值。如果我们把x视为一个函数,这就是我们寻求最小化的泛函,而此时原始-对偶算法就派上用场了。

cv::denoise_TVL1 是 OpenCV 中用于图像去噪的一个函数,它使用基于总变分(Total Variation, TV)的 L1 正则化方法来处理图像噪声。这种方法特别适合于去除图像中的加性噪声,同时尽可能保留边缘信息。

函数原型

void cv::denoise_TVL1	
(
	const std::vector< Mat > & 	observations,
	Mat & 	result,
	double 	lambda = 1.0,
	int 	niters = 30 
)	

参数

  • 参数observations 这个数组应该包含一个或多个需要被恢复的图像的噪声版本。
  • 参数result 去噪后的图像将存储在这里。不需要预先分配存储空间,因为如果必要的话会自动分配。
  • 参数lambda 对应于上述公式中的λ。随着它的增大,更平滑(模糊)的图像相比细节丰富(但可能有更多的噪声)的图像会被更优地对待。粗略地说,随着它变小,结果会更加模糊,但可以去除更多的严重异常值。
  • 参数niters 算法运行的迭代次数。当然,迭代次数越多越好,但是很难从定量的角度来精确说明这一点,因此通常使用默认值并在结果不佳时增加迭代次数。

代码示例

#include 
#include 

using namespace cv;
using namespace std;

int main()
{
    // 加载一组观察图像(例如,多次拍摄的同一场景)
    vector< Mat > observations;
    observations.push_back( imread( "noisy_image_1.jpg", IMREAD_GRAYSCALE ) );
    observations.push_back( imread( "noisy_image_2.jpg", IMREAD_GRAYSCALE ) );
    observations.push_back( imread( "noisy_image_3.jpg", IMREAD_GRAYSCALE ) );

    if ( observations[ 0 ].empty() || observations[ 1 ].empty() || observations[ 2 ].empty() )
    {
        cout << "Could not open or find the images!" << endl;
        return -1;
    }

    // 确保所有图像具有相同的大小和类型
    for ( size_t i = 1; i < observations.size(); ++i )
    {
        if ( observations[ i ].size() != observations[ 0 ].size() || observations[ i ].type() != observations[ 0 ].type() )
        {
            cout << "All images must have the same size and type." << endl;
            return -1;
        }
    }

    Mat result;

    // 使用默认参数调用 denoise_TVL1 函数
    denoise_TVL1( observations, result );

    // 显示原始图像和去噪后的结果
    imshow( "Noisy Image 1", observations[ 0 ] );
    imshow( "Denoised Image", result );

    waitKey( 0 );
    return 0;
}

运行结果

OpenCV计算摄影学(2)图像去噪函数denoise_TVL1()_第1张图片

你可能感兴趣的:(OpenCV,opencv,人工智能,计算机视觉)