我试图通过计算图像上(非重叠)滑动窗口的平均值来对图像进行像素化(\ mosaic)。为此,我尝试实现“窗口大小”和“步骤”参数。假设我的步骤不会超过图像边框。意味着如果我的图像是32X32暗淡,则窗口可以是2x2 \ 4x4 \ 8x8 \ 16x16暗淡。 Here an example
我尝试寻找一些mean operator \ mask \ convolution的组合,但没有发现任何相关的内容。
这里有一些iI试图寻找的例子:这些链接提供了我的问题的一些部分,但是我没有找到如何组合它们以实现带跳过的滑动窗口。
Numpy二维移动平均线,scipy.org /../ scipy.signal.medfilt, 在GitHub上的mosaic.py和滑动窗口操作的Numpy Vectorization 如何做这个滑动窗口,以便分别像素化部分图像。
答案 0 :(得分:0)
这是(我认为)解决问题的可能方法:
def pixelate(img, wx, wy=None):
wy = wy or wx
y, x = img.shape
if x % wx != 0 or y % wy != 0:
raise ValueError("Invalid window size.")
ny = y // wy
nx = x // wx
windowed = img.reshape((ny, wy, nx, wx))
means = windowed.mean(axis=(1, 3), keepdims=True)
means = np.tile(means, (1, wy, 1, wx))
result = means.reshape((y, x))
return result
img
是表示图像的2D NumPy数组,wx
是窗口的水平尺寸,wy
是垂直尺寸(默认为wy
})。图像必须可以被窗口大小整除。基本上它将图像数组重新整形为窗口,计算平均值,平铺结果并重新整形。
这是一个圆周的例子:
import numpy as np
import matplotlib.pyplot as plt
def pixelate(img, wx, wy=None):
wy = wy or wx
y, x = img.shape
if x % wx != 0 or y % wy != 0:
raise ValueError("Invalid window size.")
ny = y // wy
nx = x // wx
windowed = img.reshape((ny, wy, nx, wx))
means = windowed.mean(axis=(1, 3), keepdims=True)
means = np.tile(means, (1, wy, 1, wx))
result = means.reshape((y, x))
return result
# Build a circumference
WIDTH = 400
HEIGHT = 300
RADIUS = 100
THICKNESS = 10
xx, yy = np.meshgrid(np.arange(WIDTH) - WIDTH / 2, np.arange(HEIGHT) - HEIGHT / 2)
r = np.sqrt(np.square(xx) + np.square(yy))
circ = (r > (RADIUS - THICKNESS / 2)) & (r < (RADIUS + THICKNESS / 2))
circ = circ.astype(np.float32)
# Pixelate
WINDOW_SIZE = 20
circ_pix = pixelate(circ, WINDOW_SIZE)
# Show
fig = plt.figure()
ax1 = fig.add_subplot(121)
ax1.imshow(circ, "binary")
ax2 = fig.add_subplot(122)
ax2.imshow(circ_pix, "binary")
输出: