python - numpy 掩蔽平滑算法

标签 python algorithm numpy

我实现了一个基本上应用内核的平滑算法:

 [0 1 0;
  1 4 1;
  0 1 0]/8

变成一个矩阵(图像)然后修正边角,相当于设置kernel为

 [0 1 0;
  0 5 1;
  0 1 0]/8

对于左边缘,并且

 [0 0 0; 
  0 6 1; 
  0 1 0]/8

用于左上角。

我现在的目标是应用仅适用于该图像的 mask 部分的平滑。例如(参见下图),如果我有一个圆盘的方形图像,其中圆盘的值为 128+-10(+-10 是噪声效果),背景为黑色(值为 0) ,应用无限次的普通平滑算法应该给出具有恒定像素强度的方形图像。对于屏蔽平滑算法,我想屏蔽磁盘,以便应用无限次的算法应该给出 128 的均匀磁盘和黑色 (0) 背景。换句话说,只有磁盘被平滑了。

我试图避免的主要事情是背景“渗入”磁盘,使磁盘边缘模糊。我也愿意将平滑算法更改为不同的算法(例如 3x3 像素的平均值),以实现更有效的方法。

NoisyOriginal (嘈杂的原创)

Standard Smooth (正常平滑后)

MakedSmooth (蒙版后平滑)

这是我的正常平滑代码:

def SmoothImage(Matrix,N=1):
    '''Smooths a Matrix with kernel [0 1 0; 1 4 1; 0 1 0]/8'''
    A=Matrix.copy()
    for i in range(N):
        s=A.shape[0]-1
        B=A*4.0
        B[-s:,:]+=A[:s,:]
        B[0,:]+=A[0,:]
        B[:,-s:]+=A[:,:s]
        B[:,0]+=A[:,0]

        B[:s,:]+=A[-s:,:]
        B[-1,:]+=A[-1,:]
        B[:,:s]+=A[:,-s:]
        B[:,-1]+=A[:,-1]
        B*=1/8
        A=B
    return A

最佳答案

这是一种使用线性卷积加上一些技巧来保持干净边缘的方法。这个技巧基本上是通过与逆掩码卷积来计算边缘损失的质量,并将其添加到原始结果中:

import numpy as np
from scipy.signal import convolve2d

kernel = np.add.outer(*2*(np.arange(3) % 2,))**2 / 8

def perfect_edges(orig, n_iter=1, thresh=20):
    mask = orig <= thresh
    corrector = convolve2d(mask, kernel, 'same')
    result = orig.copy()
    result[mask] = 0
    for j in range(n_iter):
        result = result * corrector + convolve2d(result, kernel, 'same')
        result[mask] = 0
    result = np.round(result).astype(np.uint8)
    result[mask] = orig[mask]
    return result

picture = (np.add.outer(*2*(np.arange(-6, 7)**2,)) < 30).view(np.uint8) * 118
picture += np.random.randint(0, 21, picture.shape, dtype=np.uint8)

print(picture)
print()
print(perfect_edges(picture, 200))

示例运行:

[[ 15   0   4  10  17  13  20  12  14   1   5  16  19]
 [  1   6   9  14 132 132 129 128 135   1   5  11   5]
 [ 13  16   6 126 118 118 134 120 130 138   2   6  10]
 [ 16   3 129 129 128 129 125 134 131 132 127  18   8]
 [ 10 120 132 125 128 120 133 137 125 120 124 129   7]
 [ 10 137 119 120 119 118 137 135 135 126 118 128   0]
 [ 17 134 138 133 134 121 124 119 134 138 133 129   2]
 [  3 134 136 132 119 124 123 133 126 121 126 122  19]
 [  3 123 130 123 125 125 128 119 119 129 119 127   6]
 [  5   0 119 118 125 122 135 135 126 133 136   7   3]
 [ 11   1  13 124 121 118 136 137 127 137   2  19  15]
 [  6   7  15  19 132 132 130 125 130   9  18   9  12]
 [ 16  20   0  14   9  10   1   6   5  17  16   0   3]]

[[ 15   0   4  10  17  13  20  12  14   1   5  16  19]
 [  1   6   9  14 128 128 128 128 128   1   5  11   5]
 [ 13  16   6 128 128 128 128 128 128 128   2   6  10]
 [ 16   3 128 128 128 128 128 128 128 128 128  18   8]
 [ 10 128 128 128 128 128 128 128 128 128 128 128   7]
 [ 10 128 128 128 128 128 128 128 128 128 128 128   0]
 [ 17 128 128 128 128 128 128 128 128 128 128 128   2]
 [  3 128 128 128 128 128 128 128 128 128 128 128  19]
 [  3 128 128 128 128 128 128 128 128 128 128 128   6]
 [  5   0 128 128 128 128 128 128 128 128 128   7   3]
 [ 11   1  13 128 128 128 128 128 128 128   2  19  15]
 [  6   7  15  19 128 128 128 128 128   9  18   9  12]
 [ 16  20   0  14   9  10   1   6   5  17  16   0   3]]

关于python - numpy 掩蔽平滑算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48917761/

相关文章:

python - 用pytesseract读取低分辨率图像

python - Flask-OAuthlib "TypeError: sequence index must be integer, not ' str'”

python - 有效地计算组合和排列

c++ - 在排序和旋转的数组中搜索

algorithm - 不大于 m 的 k 个元素的最大和

python - Pandas :传递给聚合函数的对象的数据类型是什么

python - 如何使用一个函数或 for 循环导入大量 csv 数据文件?

python - 使用分而治之的方法找到列表中出现次数至少为 60% 的元素?

python - 检查 Gtk mainloop 是否正在运行

python dict到numpy结构化数组