scipy Python:仅在图像的蒙版内执行模糊

piv4azn7  于 2023-08-05  发布在  Python
关注(0)|答案(2)|浏览(124)

我有一个灰度图像和一个二进制掩模的ROI在图像。我想在灰度图像上执行模糊操作,但只能在遮罩的范围内。现在,我正在模糊整个图像,而不仅仅是去除遮罩之外的项目,但我不希望遮罩之外的像素影响我的ROI。有没有一种方法可以做到这一点,而无需建立自定义模糊功能?
希望能有这样的东西:

import scipy
blurredImage = scipy.ndimage.filters.gaussian_filter(img, sigma = 3, weight = myMask)

字符串
@stefan:

blur = 3
invmask = np.logical_not(mask).astype(int)

masked = img * mask
remaining = img * invmask

blurred = scipy.ndimage.filters.gaussian_filter(masked, sigma = blur)
blurred = blurred+remaining


扩张入路:

blur = 3
invmask = np.logical_not(mask).astype(int)    
masked = img * mask
masked2 = scipy.ndimage.morphology.grey_dilation(masked,size=(5,5))
masked2 = masked2 *invmask
masked2 = masked + masked2
blurred = scipy.ndimage.filters.gaussian_filter(masked2, sigma = blur)

vc9ivgsu

vc9ivgsu1#

将线性滤波器应用于有限域的正确方法是使用Normalized Convolution。该方法计算每个邻域内的(加权)均值,然后通过该邻域中存在的(加权)像素数进行归一化。它只使用滤波器的两个应用程序和一些琐碎的每像素操作来实现:

# normalized convolution of image with mask
filter = scipy.ndimage.gaussian_filter(img * mask, sigma = blur)
weights = scipy.ndimage.gaussian_filter(mask, sigma = blur)
filter /= weights
# after normalized convolution, you can choose to delete any data outside the mask:
filter *= mask

字符串
请注意,mask不需要仅为0和1,它可以包含中间值,表明您对该像素值的正确性有多“确定”。但通常情况下,0表示“缺失数据”,1表示可用数据。
gaussian_filter必须以浮点格式进行计算,并返回浮点值图像。整数运算在这里不会做正确的事情。
下面是一个例子:


的数据

  • 第二张图:普通过滤,然后去除蒙版外的东西。这示出了掩模外部的数据影响滤波的结果。
  • 第三张图:普通过滤,但首先将蒙版外的内容设置为零。这示出了掩码外部的零点影响滤波的结果。
  • 第4个图像:使用归一化卷积:屏蔽区域之外的数据根本不影响滤波。
bmvo0sr5

bmvo0sr52#

你想要达到的目标是不容易的,也没有你想象的那么明确。
模糊操作对应于每个像素的邻域中的像素的一些(各向同性)平均。但是在域的边界附近,邻域是不完整的,您也需要修复它

  • 通过局部地重新定义滤波器系数以避免“查询”外部像素;一种简单的方法是在这些像素上将滤波器权重设置为零;或者是
  • 通过外推ROI外部的像素值。这应该以避免沿着边界的不连续性的方式来完成,例如通过泊松重建。

对于第一种方法,您可以劫持标准过滤器,如下所示:

  • 将外部像素设置为0并模糊整个图像;当过滤器跨越轮廓时,您将仅获得内部权重和内部像素的组合;
  • 将内部像素设置为1并模糊图像;你只会得到内部权重的和
  • 取两个模糊图像的比率,使得权重正确地重新归一化。

如果图像是整数类型,则使用255而不是1以保持足够的精度。注意,在ROI之外,比率将具有零分母。

相关问题