簡體   English   中英

在python中處理大量圖像的提示

[英]Tips on processing a lot of images in python

我一直在嘗試處理兩個包含大約40000-50000個圖像的巨大文件。 但每當我嘗試將我的數據集轉換為numpy數組時,我都會遇到內存錯誤。 我只有大約8GB的內存並不是很多,但是,因為我缺乏python的經驗,我想知道是否有任何方法可以通過使用一些我不知道的python庫來解決這個問題,或者可能是優化我的代碼? 我想聽聽你對此事的看法。

我的圖像處理代碼:

from sklearn.cluster import MiniBatchKMeans
import numpy as np
import glob
import os
from PIL import Image
from sklearn.decomposition import PCA

image_dir1 = "C:/Users/Ai/Desktop/KAGA FOLDER/C/train"
image_dir2 = "C:/Users/Ai/Desktop/KAGA FOLDER/C/test1"
Standard_size = (300,200)
pca = PCA(n_components = 10)
file_open = lambda x,y: glob.glob(os.path.join(x,y))


def matrix_image(image):
    "opens image and converts it to a m*n matrix" 
    image = Image.open(image)
    print("changing size from %s to %s" % (str(image.size), str(Standard_size)))
    image = image.resize(Standard_size)
    image = list(image.getdata())
    image = map(list,image)
    image = np.array(image)
    return image
def flatten_image(image):  
    """
    takes in a n*m numpy array and flattens it to 
    an array of the size (1,m*n)
    """
    s = image.shape[0] * image.shape[1]
    image_wide = image.reshape(1,s)
    return image_wide[0]

if __name__ == "__main__":
    train_images = file_open(image_dir1,"*.jpg")
    test_images = file_open(image_dir2,"*.jpg")
    train_set = []
    test_set = []

    "Loop over all images in files and modify them"
    train_set = [flatten_image(matrix_image(image))for image in train_images]
    test_set = [flatten_image(matrix_image(image))for image in test_images]
    train_set = np.array(train_set) #This is where the Memory Error occurs
    test_set = np.array(test_set)

小編輯:我正在使用64位python

假設每個像素有一個4字節的整數,那么你試圖在(4 * 300 * 200 * 50000 /(1024)** 3)中保存大約11.2 GB的數據。 對於2字節整數的一半。

你有幾個選擇:

  1. 減少要在內存中保留的圖像的數量或大小
  2. 使用文件或數據庫來保存數據而不是內存(某些應用程序可能太慢)
  3. 更有效地使用你擁有的記憶......

而不是從列表復制到numpy,這將暫時使用兩倍的內存量,如下所示:

test_set = [flatten_image(matrix_image(image))for image in test_images]
test_set = np.array(test_set)

做這個:

n = len(test_images)
test_set = numpy.zeros((n,300*200),dtype=int)
for i in range(n):
    test_set[i] = flatten_image(matrix_image(test_images[i]))

由於您的文件是JPEG並且您有300x200圖像,因此對於24位彩色圖像,您每個文件大約需要1.4 MB,而且總體上至少要高達40.2 GB:

In [4]: import humanize # `pip install humanize` if you need it

In [5]: humanize.naturalsize(300*200*24, binary=True)
Out[5]: '1.4 MiB'

In [6]: humanize.naturalsize(300*200*24*30000, binary=True)
Out[6]: '40.2 GiB'

如果你有灰度,你可能有8位圖像,響應為13.4 GB:

In [7]: humanize.naturalsize(300*200*8, binary=True)
Out[7]: '468.8 KiB'

In [8]: humanize.naturalsize(300*200*8*30000, binary=True)
Out[8]: '13.4 GiB'

這僅適用於一個副本。 根據操作,這可能會變得更大。

變得更大

您總是可以在具有更多內存的服務器上租用一些時間。

從RAM量來看這些並不是考慮哪種服務器最適合您的工作負載的唯一方法。 提供商之間還存在其他差異,包括IOPS,內核數量,CPU類型等。

訓練后測試

訓練模型后,您不需要全套訓練數據。 刪除內存不足的內容。 在Python中,這意味着不保留對數據的引用。 奇怪的野獸,是的。

這可能意味着設置您的訓練數據並在僅返回您需要的功能中創建模型。

減少內存占用

讓我們想象一下,你可以將它全部存儲在內存中。 您可以在此處進行的一項改進是直接從PIL圖像轉換為numpy數組 不復制現有數組,它是原始數據的視圖。 但是,看起來您需要在向量空間中展平

image = Image.open(image)
print("changing size from %s to %s" % (str(image.size), str(Standard_size)))
image = image.resize(Standard_size)
np_image = np.asarray(image).flatten()

編輯:實際上,這有助於您的代碼的可維護性,但無助於性能。 您可以單獨對函數中的每個圖像執行此操作。 垃圾收集器會扔掉舊東西。 繼續前進,沒有什么可看的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM