目标
在本教程中,您将了解使用 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\) 是逐元素矩阵乘法(哈达玛积)。公式更新为
\[ 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
与磁盘上的文件关联的文件存储的“黑盒”表示。
定义 core.hpp:102
解释
以下示例演示了图像修复的用法。使用相同的输入和三种不同的损坏类型创建了三个人工图像。在实际应用中,输入图像已经给出,但在这里我们自己创建了它。
首先,我们必须加载我们的图像和三个用于人工损坏创建的掩码。
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)