目标
在本教程中,您将学习如何使用 F 变换进行图像修复。它包含
简介
本教程的目标是展示逆 F 变换可以用于图像重建。图像重建是指重建损坏的图像,其中损坏包括原始图像中不包含的所有内容。它可以是噪声、文本、划痕等。建议借助近似技术解决重建问题。这意味着我们将寻找一个近似图像,该图像与给定图像接近,同时不包含我们认为是损坏的部分。此任务称为图像修复。
模糊变换应用
正如我在之前的教程中展示的,F 变换是一种模糊数学工具,在图像处理中非常有用。让我重写公式,并使用之前引入的内核 \(g\)
\[ F^0_{kl}=\frac{\sum_{x=0}^{2h+1}\sum_{y=0}^{2h+1} \iota_{kl}(x,y) g(x,y)}{\sum_{x=0}^{2h+1}\sum_{y=0}^{2h+1} g(x,y)}, \]
其中 \(\iota_{kl} \subset I\) 以像素 \((k \cdot h,l \cdot h)\) 为中心,\(g\) 是内核。为了进行图像处理,使用二值掩码 \(S\) 如下
\[ g^s_{kl} = g \circ s_{kl} \]
其中 \(s_{k,l} \subset S\)。掩码 \(S\) 的子区域 \(s\) 对应于图像 \(I\) 的子区域 \(\iota\)。运算符 \(\circ\) 是逐元素矩阵乘法(Hadamard 积)。公式更新为
\[ F^0_{kl}=\frac{\sum_{x=0}^{2h+1}\sum_{y=0}^{2h+1} \iota_{kl}(x,y) g^s(x,y)}{\sum_{x=0}^{2h+1}\sum_{y=0}^{2h+1} g^s(x,y)}. \]
更多详细信息可以在相关论文中找到。
代码
{
Mat I = imread(
"input.png");
Mat mask1 = imread(
"mask1.png", IMREAD_GRAYSCALE);
Mat mask2 = imread(
"mask2.png", IMREAD_GRAYSCALE);
Mat mask3 = imread(
"mask3.png", IMREAD_GRAYSCALE);
Mat input1, input2, input3;
Mat output1, output2, output3, output4;
ft::inpaint(input1, mask1, output1, 2, ft::LINEAR, ft::ONE_STEP);
ft::inpaint(input2, mask2, output2, 2, ft::LINEAR, ft::MULTI_STEP);
ft::inpaint(input3, mask3, output3, 2, ft::LINEAR, ft::MULTI_STEP);
ft::inpaint(input3, mask3, output4, 2, ft::LINEAR, ft::ITERATIVE);
imwrite("output1_inpaint.png", output1);
imwrite("output2_inpaint.png", output2);
imwrite("output3_inpaint.png", output3);
imwrite("output4_inpaint.png", output4);
imwrite("input1.png", input1);
imwrite("input2.png", input2);
imwrite("input3.png", input3);
return 0;
}
void copyTo(OutputArray m) const
将矩阵复制到另一个矩阵。
int main(int argc, char *argv[])
定义 highgui_qt.cpp:3
说明
下面的示例演示了图像修复的用法。使用相同的输入和三种不同类型的损坏创建三个人工图像。在实际使用中,输入图像将已呈现,但在这里我们自己创建了它。
首先,我们必须加载我们的图像和用于人工损坏创建的三个掩码。
Mat I = imread(
"input.png");
Mat mask1 = imread(
"mask1.png", IMREAD_GRAYSCALE);
Mat mask2 = imread(
"mask2.png", IMREAD_GRAYSCALE);
Mat mask3 = imread(
"mask3.png", IMREAD_GRAYSCALE);
请注意,掩码必须加载为 IMREAD_GRAYSCALE。
在下一步中,掩码用于损坏我们的输入图像。
Mat input1, input2, input3;
使用掩码,我们在相同的输入图像上应用了三种不同类型的损坏。这是结果。
input1、input2 和 input3
不要忘记,在实际使用中,图像 input1、input2 和 input3 是自然创建的,并直接用作输入。
接下来是输出图像的声明。在以下几行中,应用了图像修复的方法。让我逐一解释三种不同的算法。
第一个是 ONE_STEP。
ft::inpaint(input1, mask1, output1, 2, ft::LINEAR, ft::ONE_STEP);
ONE_STEP 算法简单地计算直接 F 变换,使用半径为 2 的内核(如方法调用中指定)忽略损坏的部分。逆 F 变换使用来自附近组件的值填充缺失区域。由您决定选择足够大的半径。
第二个是 MULTI_STEP。
ft::inpaint(input2, mask2, output2, 2, ft::LINEAR, ft::MULTI_STEP);
ft::inpaint(input3, mask3, output3, 2, ft::LINEAR, ft::MULTI_STEP);
MULTI_STEP 算法的工作方式相同,但如果发现半径不足,则会自动增加定义的半径(在本例中为 2)。如果您想填充孔,但不确定需要多大的半径,您可以选择 MULTI_STEP,让计算机来决定。将找到可能的最小值。
最后一个是 ITERATIVE。
ft::inpaint(input3, mask3, output4, 2, ft::LINEAR, ft::ITERATIVE);
在大多数情况下,最佳选择是 ITERATIVE。这种处理方式对小类型的损坏使用基本函数的小半径,对较大的孔使用较大的半径。
output1 (ONE_STEP)、output2 (MULTI_STEP)、output3 (MULTI_STEP)、output4 (ITERATIVE)