【发布时间】:2015-09-10 08:05:54
【问题描述】:
我有大量想要模糊处理的大图像(例如 15000x15000 像素)。我需要使用距离函数模糊图像,因此我离图像中的某些区域越远,模糊应该越重。我有一张距离图,描述了给定像素与这些区域的距离。
由于图片数量众多,我必须考虑性能。我看过 NumPY/SciPY,它们有一些很棒的功能,但它们似乎使用固定的内核大小,我需要根据与前面提到的区域的距离来减小或增加内核大小。
如何在 python 中解决这个问题?
更新:到目前为止,我的解决方案基于 rth 的回答:
# cython: boundscheck=False
# cython: cdivision=True
# cython: wraparound=False
import numpy as np
cimport numpy as np
def variable_average(int [:, ::1] data, int[:,::1] kernel_size):
cdef int width, height, i, j, ii, jj
width = data.shape[1]
height = data.shape[0]
cdef double [:, ::1] data_blurred = np.empty([width, height])
cdef double res
cdef int sigma, weight
for i in range(width):
for j in range(height):
weight = 0
res = 0
sigma = kernel_size[i, j]
for ii in range(i - sigma, i + sigma + 1):
for jj in range(j - sigma, j + sigma + 1):
if ii < 0 or ii >= width or jj < 0 or jj >= height:
continue
res += data[ii, jj]
weight += 1
data_blurred[i, j] = res/weight
return data_blurred
测试:
data = np.random.randint(256, size=(1024,1024))
kernel = np.random.randint(256, size=(1024,1024)) + 1
result = np.asarray(variable_average(data, kernel))
使用上述设置的方法运行大约需要 186 秒。这是我可以期望最终从方法中挤出来的,还是我可以使用优化来进一步提高性能(仍然使用 Python)?
【问题讨论】:
-
这并不能回答您的问题,但如果您真的关心性能,您应该尝试 C++ 和 OpenCV。
-
你想要什么样的模糊?高斯?盒子模糊?模糊是否必须在数学上准确,还是为了艺术效果和“如果看起来足够好,就足够好了”?此外,模糊量是否与复杂 3D 场景中的深度值有关?您是否需要担心不会将焦点附近物体的颜色值溢出到远离焦点的表面等?
-
@coincoin:由于我缺乏 C++ 知识,我想远离 C++,但我的想法完全一样 :) @samgak:我需要图像具有无缝模糊,它应该只是看起来足够好,这是为了视觉目的。我只需要所选像素周围最近的
X像素的平均值,不需要花哨的东西。图片是二维照片。 -
作为旁注,您可以
return data_blurred.base以避免调用np.asarray的需要。同样使用cpdef而不是def可能更可取(对性能没有影响)。最后,对于任何高性能 C 代码,请检查您的编译标志。例如在我的系统(Linux Gentoo)上,我惊讶地发现在setup.py中设置extra_compile_args=['-O3', '-march=native'],extra_link_args=['-O3', '-march=native']导致某些代码的速度提高了~2 倍,而在Windows 上的同一台机器上使用Ananconda,速度提升可以忽略不计。
标签: python image-processing numpy scipy cython