微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用二维数组更快地迭代 for 循环

如何解决使用二维数组更快地迭代 for 循环

我在计算视差图估计误差的优化方面遇到问题。

为了计算错误,我为每个错误创建了一个带有调用方法的类。我需要迭代每个像素才能得到错误。 这个数组很重要,因为我正在迭代 1937 x 1217 图像的大小。你知道如何优化吗?

这是我的方法代码

编辑:

def mreError(self):
    s_gt = self.ref_disp_norm
    s_all = self.disp_bin
    s_r = self.disp_norm 

    s_gt = s_gt.astype(np.float32)
    s_r = s_r.astype(np.float32)
    n,m = s_gt.shape
    all_arr = []

    for i in range(0,n):
        for j in range(0,m):

            if s_all[i,j] == 255:
                if s_gt[i,j] == 0:
                    sub_mre = 0
                else:   
                    sub_mre = np.abs(s_gt[i,j] - s_r[i,j]) / s_gt[i,j]
                all_arr.append(sub_mre)

    mre_all = np.mean(all_arr)
    return mre_all

解决方法

您可以简单地使用数组运算符,而不是将它们应用于 for 循环中的每个元素:

import numpy as np

# Creating 2000x2000 Test-Data
s_gt = np.random.randint(0,2,(2000,2000)).astype(np.float32)
s_r = np.random.randint(0,2000)).astype(np.float32)
s_all = np.random.randint(0,256,2000)).astype(np.float32)


def calc(s_gt,s_r,s_all):
    n,m = s_gt.shape
    all_arr = []
    for i in range(0,n):
        for j in range(0,m):
            if s_gt[i,j] == 0:
                sub_mre = 0
            else:   
                sub_mre = np.abs(s_gt[i,j] - s_r[i,j]) / s_gt[i,j]
    
            if s_all[i,j] == 255:
                all_arr.append(sub_mre)
    
    mre_all = np.mean(all_arr)
    return mre_all

def calc_optimized(s_gt,s_all):
    sub_mre = np.abs((s_gt-s_r)/s_gt)
    sub_mre[s_gt==0] = 0
    return np.mean(sub_mre[s_all == 255])

当我测试两种不同方法的速度时:

%time calc(s_gt,s_all)
Wall time: 27.6 s
Out[53]: 0.24686379928315413

%time calc_optimized(s_gt,s_all)
Wall time: 63.3 ms
__main__:34: RuntimeWarning: divide by zero encountered in true_divide
__main__:34: RuntimeWarning: invalid value encountered in true_divide
Out[54]: 0.2468638
,

您的方法的直接矢量化是

def method_1(self):
    # get s_gt,s_all,s_r
    sub_mre = np.zeros((s_gt.shape),dtype=np.float32)
    idx = s_gt != 0
    sub_mre[idx] = np.abs((s_gt[idx] - s_r[idx]) / s_gt[idx])
    return np.mean(sub_mre[s_all == 255])

但由于您只对 s_all 为 255 的像素进行平均,您也可以先过滤那些像素,然后再做其余的工作

def method_2(self):
    idx = s_all == 255
    s_gt = s_gt[idx].astype(np.float32)
    s_r = s_r[idx].astype(np.float32)
    sub_mre = np.zeros_like(s_gt)
    idx = s_gt != 0
    sub_mre[idx] = np.abs((s_gt[idx] - s_r[idx]) / s_gt[idx])
    return np.mean(sub_mre)

就我个人而言,我更喜欢第一种方法,除非第二种方法的结果要快得多。只调用一次函数并花费,例如 40 ms vs 5 ms 并不明显,函数的可读性更重要。

,

您可以将图像设为灰色(这将大大加快计算速度)请查看此 link 如何做到这一点。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。