我正在尝试编写一个像素插值(合并?)算法(例如,我想取四个像素并取它们的平均值并将该平均值作为新像素产生)。我在加快“分区”过程的步幅技巧方面取得了成功,但实际计算速度确实很慢。对于 256x512 16 位灰度图像,我得到平均代码以在我的机器上花费 7 秒。我必须根据数据集处理从 2k 到 20k 的图像。目的是减少图像的噪音(我知道我提出的方法会降低分辨率,但这对我的目的来说可能不是一件坏事)。
import numpy as np
from numpy.lib.stride_tricks import as_strided
from scipy.misc import imread
import matplotlib.pyplot as pl
import time
def sliding_window(arr, footprint):
""" Construct a sliding window view of the array"""
t0 = time.time()
arr = np.asarray(arr)
footprint = int(footprint)
if arr.ndim != 2:
raise ValueError("need 2-D input")
if not (footprint > 0):
raise ValueError("need a positive window size")
shape = (arr.shape[0] - footprint + 1,
arr.shape[1] - footprint + 1, footprint, footprint)
if shape[0] <= 0:
shape = (1, shape[1], arr.shape[0], shape[3])
if shape[1] <= 0:
shape = (shape[0], 1, shape[2], arr.shape[1])
strides = (arr.shape[1]*arr.itemsize, arr.itemsize,
arr.shape[1]*arr.itemsize, arr.itemsize)
t1 = time.time()
total = t1-t0
print "strides"
print total
return as_strided(arr, shape=shape, strides=strides)
def binning(w,footprint):
#the averaging block
#prelocate memory
binned = np.zeros(w.shape[0]*w.shape[1]).reshape(w.shape[0],w.shape[1])
#print w
t2 = time.time()
for i in xrange(w.shape[0]):
for j in xrange(w.shape[1]):
binned[i,j] = w[i,j].sum()/(footprint*footprint + 0.0)
t3 = time.time()
tot = t3-t2
print tot
return binned
Output:
5.60283660889e-05
7.00565886497
是否有一些内置/优化的功能可以满足我的需求,或者我应该尝试做一个 C 扩展(甚至是其他东西)?
下面是代码的附加部分,只是为了完整起见,因为我认为函数在这里是最重要的。图像绘图很慢,但我认为有一种方法可以改进它,例如这里
for i in range(2000):
arr = imread("./png/frame_" + str("%05d" % (i + 1) ) + ".png").astype(np.float64)
w = sliding_window(arr,footprint)
binned = binning(w,footprint)
pl.imshow(binned,interpolation = "nearest")
pl.gray()
pl.savefig("binned_" + str(i) + ".png")
enter code here
我正在寻找的可以称为插值。我只是使用了建议我这样做的人使用的术语。可能这就是我找到直方图相关内容的原因!
除了 median_filter 我尝试了 scipy.ndimage 中的 generic_filter 但那些并没有给我想要的结果(它们没有像卷积那样的“有效”模式,即这些依赖于在移动内核环绕时超出数组的范围)。我在代码审查中问过,似乎 stackoverflow 会更适合这个问题。