要求一种更快的方法来从图像中提取数据

时间:2020-07-23 15:04:01

标签: python image-processing data-mining

目前,我正在编写代码,在其中我使用Opencv / PIL提取图像RGB值(两者均尝试)。 然后,我通过一个函数来计算它们的均值和中位数,以及上部和下部的均值和中位数。 目前,我的代码每秒大约需要处理1张图片,而我需要对存储在其类别的不同子文件夹中的10,000余张图片进行处理。 我将numpy函数用于均值和中位数。

我有更快的方法吗?

编辑:图像大小各异,尺寸从1x1到1000x100不等,格式为jpg,png和bmp

至于代码,我知道访问图像不应该花很长时间,但是问题在于计算这些数组的均值和中值。
请在其外观下方添加一个代码段(如果效果不佳,我会提前道歉) 最后,我还使用xlwt将所有这些均值和中值写到excel工作表中,我希望它们也不要花费很长时间。

我使用os.walk遍历目录,然后使用
img = os.path.join(dirName,fname)
并从另一个文件中定义的函数获取值
值= rgbavg(img)

image = cv2.imread(image_path)
    img = np.array(image)
    img = img.transpose(2,0,1).reshape(3,-1)
    x, size = img.shape
    avg = np.mean(img, axis = 1)

    for i in range(0,3):
        upper = np.array([])
        lower = np.array([])
        for ele in img[i]:
            if ele > avg[i]:
                upper = np.append(upper,ele)
            else:
                lower = np.append(lower,ele)

        if upper.size != 0:
            mean = np.mean(upper)
            avg = np.append(avg,mean)
        else:
            avg = np.append(avg,0)
        if lower.size != 0:
            mean = np.mean(lower)
            avg = np.append(avg,mean)
        else:
            avg = np.append(avg,0)

1 个答案:

答案 0 :(得分:1)

可能是您的程序只花大量时间等待读写操作和许多循环。

实际答案已更新

您可以通过使用多个过程来缓解等待的部分。我认为最简单的方法是使用游泳池。无论您拥有多少内核,这也可以提高代码速度。

首先,您需要准备数据(收集所有文件/文件路径的列表)

然后您将其作为参数传递,以便Pool创建过程并保存结果

import multiprocessing
import time

files = ["img1.jpeg", "img2.jpeg", "img3.jpeg", "img4.jpeg"]

def process_image(path):
    # process image and return your data
    # time.sleep is only here to show that a different process is running as it executes faster than pool starts processes
    time.sleep(1)
    return [[0,0,0], [14,14,14], multiprocessing.current_process().name]

if __name__ == '__main__':
    with multiprocessing.Pool(processes=4) as pool:
        results = pool.map(process_image, files)
        print(results)

已更新:

检查原始代码后,我发现过滤需要花费很长时间(在这种情况下,将数组中的平均值分开上下)。 Numpy的筛选器更快:

boolean_array = img_array <|> | = value#返回一个布尔数组

filtered = img_array [boolean_array]#返回过滤后的列表

import multiprocessing
import numpy
import cv2


def process_image(xyz):
    img = numpy.random.randint(255, size=(1000,1000,3),dtype=numpy.uint8)
                      .transpose(2,0,1).reshape(3,-1)
    avg = numpy.mean(img, axis = 1)

    x, size = img.shape

    for i in range(0,3):
        upper = img[i][img[i] >= avg[i]]
        lower = img[i][img[i] < avg[i]]
        if upper.size != 0:
            # Why you are saving these idk but ok
            mean = numpy.mean(upper)
            avg = numpy.append(avg,mean)
        else:
            avg = numpy.append(avg,0)
        if lower.size != 0:
            mean = numpy.mean(lower)
            avg = numpy.append(avg,mean)
        else:
            avg = numpy.append(avg,0)
    
    return [avg, mean, multiprocessing.current_process().name]

if __name__ == '__main__':
    with multiprocessing.Pool(processes=4) as pool:
        results = pool.map(process_image, range(0,12))
        print(results)

这是添加了多处理功能