我正在实施一个简单的算法来对“受损”的图像进行绘画。我有一个预定义的掩码,指定需要修复的区域。我的策略是从遮蔽区域的边界开始,用相邻的非零像素的中心平均值绘制每个像素,重复直到没有未知像素为止。
__init__
这很好用,但效率不高。是否可以使用大多数矩阵运算来矢量化这种方法?有人知道一种更有效的方法来实现这个算法吗?
答案 0 :(得分:2)
如果我理解你的问题陈述,你会得到一个掩码,你希望在这个掩码中用围绕掩码中每个像素的邻域像素的平均值填充这些像素。另一个约束是图像被定义为使得属于相同空间位置中的掩模的任何像素在该掩模中为零。你是从面具的边界开始,并将信息传播到面具的内部。鉴于此算法,遗憾的是您无法使用标准过滤技术执行此操作,因为当前时间步长取决于之前的时间步长。
图像过滤机制,例如imfilter
或conv2
,由于此依赖性,无法在此处工作。
因此,我能做的就是帮助你加快循环内部的速度,希望这会让你整体加快速度。我将向您介绍一个名为im2col
的函数。这是来自图像处理工具箱,并且假设您可以使用imfilter
,我们可以使用此功能。
im2col
创建一个二维矩阵,使每列都是一个像素邻域展开到一个向量中。它是如何工作的,列主要顺序中的每个像素邻域都被抓取,因此我们在图像的左上角得到一个像素邻域,然后向下移动一行,然后向下移动另一行,直到我们到达最后一行。然后我们移动一列并重复相同的过程。对于我们拥有的每个像素邻域,它将展开为单个向量,输出将是MN x K
矩阵,其中每个像素邻域的邻域大小为M x N
,并且{{1}邻里。
因此,在循环的每次迭代中,我们可以将当前的修复图像的像素邻域展开为单个矢量,确定哪些像素邻域不为零,并从那里确定每个像素邻域有多少个零值。这些选定的像素邻域。之后,我们计算这些非零列的平均值,忽略零元素。完成后,我们会更新图像并转到下一次迭代。
我们首先需要做的是用1像素边框填充图像,以便我们能够抓住超出图像边界的邻域。您也可以使用padarray
,也可以使用图像处理工具箱。
因此,我们可以这样做:
K