首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >根据像素的位置有效地对每个像素应用函数

根据像素的位置有效地对每个像素应用函数
EN

Stack Overflow用户
提问于 2019-05-09 21:09:12
回答 1查看 142关注 0票数 2

我想高效地迭代给定图像的每个像素,并基于像素的位置,应用一个函数并将输出放在这个位置。

这是我尝试过的:

代码语言:javascript
复制
def point_gaussian_value(p1, p2, sigma=0.8):
    x1, y1 = p1
    x2, y2 = p2

    return np.exp(-1 * (np.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) / sigma ** 2))

point_annotation = np.zeros_like(sample).astype(np.float32)
for j in range(sample.shape[0]):
    for k in range(sample.shape[1]):

        value = point_gaussian_value(p1=(j, k), p2=(row[header[i]], row[header[i + 1]]))
        point_annotation[j, k] = point_gaussian_value(p1=(j, k), p2=(20, 20))

虽然它很天真,而且效率非常低,特别是对于大图像。我知道我可以向量化一个函数,这样所有的计算都可以并行高效地完成,但我不确定是否可以/如何向量化一个函数,该函数获得每个像素的位置。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-09 21:26:44

假设函数接收的是行和列的索引,您可以使用np.aranges作为x1y1坐标,以向量化的方式直接计算所有值:

代码语言:javascript
复制
rows = np.arange(sample.shape[0])
cols = np.arange(sample.shape[1])
x2, y2 = (row[header[i]], row[header[i + 1]])
out = np.exp(-1 * (np.sqrt((x2 - rows[:,None])**2 + (y2 - cols)**2) / 0.8**2))

我们还可以通过使用numexpr模块来加速计算:

代码语言:javascript
复制
import numexpr as ne
rows = np.arange(sample.shape[0])
cols = np.arange(sample.shape[1])
x2, y2 = (row[header[i]], row[header[i + 1]])
out = ne.evaluate('exp(-1 * sqrt((x2- rows2D)**2 + (y2- cols)**2) / 0.8**2)', 
                 {'rows2D': rows[:,None]})

快速检查和计时:

代码语言:javascript
复制
n_rows = 1000
n_cols = 1000
rows = np.arange(n_rows)
cols = np.arange(n_cols)
x2, y2 = 10, 12
out = ne.evaluate('exp(-1*sqrt((x2- rows2D)**2 + (y2- cols)**2) / 0.8**2)', 
                 {'rows2D': rows[:,None]})

np.allclose(out, point_annotation, rtol=1e-5)
# True

代码语言:javascript
复制
def current_approach(n_rows, n_cols, x2, y2):
    point_annotation = np.zeros((n_rows,n_cols)).astype(np.float32)
    for j in range(n_rows):
        for k in range(n_cols):
            value = point_gaussian_value(p1=(j, k), p2=(x2,y2))
            point_annotation[j, k] = point_gaussian_value(p1=(j, k), p2=(x2,y2))

def approach_1(n_rows, n_cols, x2, y2):
    rows = np.arange(n_rows)
    cols = np.arange(n_cols)
    out = np.exp(-1 * (np.sqrt((x2- rows[:,None])**2 + (y2- cols)**2) / 0.8**2))

def approach_2(n_rows, n_cols, x2, y2):
    rows = np.arange(n_rows)
    cols = np.arange(n_cols)
    out = ne.evaluate('exp(-1*sqrt((x2- rows2D)**2 + (y2- cols)**2) / 0.8**2)', 
                                   {'rows2D': rows[:,None]})

%timeit current_approach(n_rows, n_cols, x2, y2)
# 10.7 s ± 471 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit approach_1(n_rows, n_cols, x2, y2)
# 59.3 ms ± 426 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit approach_2(n_rows, n_cols, x2, y2)  
# 965 µs ± 43.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

使用第二种方法可以提高11000x的速度!

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56060188

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档