【问题标题】:Code taking too long to execute while doing batch processing of Image对图像进行批处理时代码执行时间过长
【发布时间】:2020-09-05 10:44:23
【问题描述】:

我正在尝试为每个图像计算一定范围的天顶角平均温度

我正在使用 for 循环来执行上述任务。在循环内部,我计算每个像素到中心的距离,然后根据距离应用条件。

图像有很多不需要的反射,我正在使用 df_con 数据框将其移除。

循环需要 1 分 30 秒来处理一张图像上的所有操作(仅 24 张图像需要 38 分钟)。有没有办法提高代码的速度。

### Reading all the images inside the Images folder
X_data = []
files = glob.glob ("Images/*.jpg"). #  Total 17,000 images of(480*640*3)
files.sort(key=os.path.getmtime, reverse=True)


X_data = [cv.imread(img) for img in files]

image_data = np.array(X_data)

T_hot = np.array([])

for r in tqdm(range(image_data[:,0,0,0].size)):

    ##Converting RGB image to grey scale image 
    grey = cv.cvtColor(image_data[r],cv.COLOR_BGR2GRAY)


    Z = grey.reshape(-1,1)

    Tem = np.array([])

    Tmax = 25 
    Tmin = -10 

    Zmax = 255 
    Zmin = 0
    c = -10

    m = (Tmax - Tmin) / (Zmax - Zmin)

    zenith = np.array([])
    theta = np.around(np.arange(0,90,90/200),6)

    for i in range(0,480):
        for j in range(0,640):

            # Calculating distance of each pixel from the center.
            r = np.around(np.sqrt((332 - j)**2 + (235 - i)**2))

            # Assigning zxenith angle to each pxl.
            # Calculating Temperature of indexed pxl.

            if r < 200:
                k = theta[theta == np.around((r*90/200),6)]
                zenith = np.append(zenith,k)
                T =  (m*grey[i,j]) + c 
                Tem = np.append(Tem,T)
            else:
                k = 120
                zenith = np.append(zenith,k) 
                T = 255
                Tem = np.append(Tem,T)



    # creating panda dataframe 
    df = pd.DataFrame({'Pxl':Z[:,0],'Tem':Tem[:],'zenith':zenith[:]})

    # Fetching the Image mask data points 
    df_con = pd.read_excel('contour.xlsx')

    dataset_final = pd.merge(df,df_con, how='outer', on=None, \
                            left_index=True, right_index=True, sort=True)
    dataset_final = dataset_final[dataset_final['pxl_new'] < 255]

    df_0 = pd.DataFrame(0, index=range(Z.shape[0]), columns={'Null'}) 

    df_image = pd.merge(dataset_final,df_0, how='outer', on=None, \
                            left_index=True, right_index=True,\
                         sort=True)

    df_image = df_image[['Pxl','Tem','zenith']].fillna(255)


    df_target = dataset_final[(dataset_final['zenith'] >= 65) & \
                              (dataset_final['zenith'] <= 85)]
    mean = np.mean(df_target[['Tem']].values)
    T_hot = np.append(T_hot, mean)

【问题讨论】:

  • 您是否真的一次性将所有 17,000 张图像全部加载到内存中以计算它们的平均值。您通常只需要一个累加器图像,然后一次将其他图像添加到其中。您是否也真的将它们全部加载为颜色,只是为了转换为灰度?如果是这样,您将浪费 51,000 倍所需的内存。考虑直接将它们加载为灰度。
  • 您不仅一次读取所有图像,然后将它们连接成一个大矩阵,以便将它们一一提取以进行处理。您真的应该考虑将它们一一加载并单独处理。接下来,您应该分析您的代码以了解哪些操作最耗时,并首先专注于改进这些操作。
  • @MarkSetchell 我实际上是在尝试计算平均温度并将其绘制为每个图像的时间戳。这就是为什么我一次加载所有图像的原因。我尝试以灰度加载所有图像,是的,它已将图像加载时间从 2:30 秒显着减少到 0.35 秒。另外,我没有得到累加器图像的概念。

标签: python-3.x pandas image-processing optimization batch-processing


【解决方案1】:

所以,经过 3 天漫长的奋斗,我设法部分解决了问题。我注意到我的代码中有三件事:

  1. 我正在读取所有彩色图像,然后将其转换为灰度,这是一个不必要的额外步骤,并导致大量计算时间。感谢@Mark Setchell,他为我指出了这一点。
X_data = []

files = glob.glob ("Images/*.jpg")
files.sort(key=os.path.getmtime, reverse=True)
for img in tqdm(files):
# Reading images in greyscale
    X = cv.imread(img,0);
    X_data.append(X)
  1. 我在循环中使用 panda 数据框来执行索引操作。虽然 panda 数据框让我们的生活变得轻松,但它需要大量的计算时间。所以,我决定使用numpy array 而不是panda DataFrame

  2. 我为下面的代码块实现了多处理。

for i in range(0,480):
        for j in range(0,640):

            r = np.around(np.sqrt((332 - j)**2 + (235 - i)**2))

            if r < 200:
                k = theta[theta == np.around((r*90/200),6)]
                zenith = np.append(zenith,k)
                T =  (m*grey[i,j]) + c 
                Tem = np.append(Tem,T)
            else:
                k = 120
                zenith = np.append(zenith,k) 
                T = 255
                Tem = np.append(Tem,T)

现在新的代码块是这样的:

def temperature(count):
    zenith = np.array([])
    Tem = np.array([])

    theta = np.around(np.arange(0, 90, 90 / 200), 6)
    for j in range(0, 640):
        r = np.around(np.sqrt((332 - j) ** 2 + (235 - count) ** 2))

        if r < 200:
            k = theta[theta == np.around((r * 90 / 200), 6)]
            zenith = np.append(zenith,k)
            T = (m * grey[count, j]) + c
            Tem = np.append(Tem,T)
        else:
            k = 120
            zenith = np.append(zenith,k)
            T = 20
            Tem = np.append(Tem,T)

    result = np.vstack((zenith, Tem)).T
    return np.array(result)

if __name__ == '__main__':
        pool = Pool(cpu_count())
        result = pool.map(temperature, range(0,480))
        pool.close()
        res = np.array(result)
        Tem = res[:,:,1].reshape(-1,1)
        zenith = res[:,:,0].reshape(-1,1)

通过实施上述更改,我设法减少了 1min30sec to 2sec 的单个图像的处理时间。我相信有更好的方法可以进一步优化。请随时提供您的解决方案。对于像我这样的新手来说,这将是一个很大的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    • 2012-11-27
    相关资源
    最近更新 更多