Python 影像處理_釋放記憶體避免OOM崩潰

更新 發佈閱讀 6 分鐘

在使用 Python 進行影像處理資料科學運算 時,我們常常需要載入大量圖片或產生大量矩陣。

如果沒有妥善管理記憶體,程式很容易因為 RAM 爆滿 (Out Of Memory, OOM) 而崩潰。

尤其是在舊電腦win7 32位元狀況下,容易發生這個問題​。

MemoryError: Unable to allocate 12.9 MiB for an array with shape (1628, 2775, 3)

and data type uint8


本文將用範例與實驗結果,完整說明:

  • 為什麼 delgc.collect() 是必要的
  • 什麼情況下記憶體會暴增
  • 正確釋放記憶體的方法與效益

測試結果圖

沒有釋放記憶體,就會一直疊加。

raw-image

釋放記憶體,保持穩定,完全不會隨著迴圈增加。

raw-image

為什麼需要記憶體管理

Python 內建的垃圾回收(Garbage Collection, GC)會自動釋放不再被引用的變數,但在影像處理這種情境下,GC 不一定能及時處理記憶體釋放,原因包括:

  1. 變數還有引用
    影像處理過程中,如果把處理結果存進一個列表或變數,Python 不會釋放這塊記憶體。
  2. NumPy 與底層 C 記憶體池
    NumPy 陣列的底層記憶體由 C 管理,GC 只會釋放 Python 物件,不會立即歸還底層記憶體給作業系統。
  3. 記憶體碎片化
    記憶體釋放不及時,或者釋放後無法馬上回收,導致表面上看起來記憶體佔用不斷增加。

程式範例

import numpy as np
import gc
import psutil
import os
import time

def print_memory_usage(note=""):
process = psutil.Process(os.getpid())
print(f"[Memory {note}] {process.memory_info().rss / 1024 / 1024:.2f} MB")

def simulate_processing(num_images=30, image_size=(4000, 4000, 3), release_memory=False):
"""
num_images: 模擬影像數量
image_size: 每張影像大小
release_memory: 是否釋放記憶體
"""
print(f"\n{'='*20} {'WITH' if release_memory else 'WITHOUT'} MEMORY RELEASE {'='*20}\n")

processed_images = [] # 模擬把每張處理後的結果保留下來

for i in range(num_images):
print_memory_usage(f"Before creating image {i+1}")

# 模擬創造一張高解析度影像 (RGB)
img = np.random.randint(0, 256, size=image_size, dtype=np.uint8)

# 模擬簡單處理:轉灰階
gray = np.mean(img, axis=2).astype(np.uint8)

# 把結果暫存 (模擬程式需要暫時保存結果)
processed_images.append(gray)

print_memory_usage(f"After processing image {i+1}")

if release_memory:
# 釋放當前影像記憶體
del img
del gray
processed_images.clear() # 清空暫存
gc.collect()
print_memory_usage(f"After GC image {i+1}")
else:
print_memory_usage(f"Image {i+1} kept in memory")

time.sleep(0.3)

# 測試沒釋放記憶體
simulate_processing(num_images=10, release_memory=False)

# 測試有釋放記憶體
simulate_processing(num_images=10, release_memory=True)

什麼時候需要 gc.collect()

  • 需要釋放大物件或大量 NumPy 陣列時
    如影像批次處理、影片逐幀分析、深度學習資料預處理。
  • 長時間執行的程式
    例如服務型程式、持續運行的監控系統。
  • 迴圈產生大量資料
    當記憶體曲線持續上升,就代表該手動釋放。

最佳實踐建議

  1. 盡量不要保留不必要的變數
    處理完一張影像立即釋放,不要一次堆積。
  2. 批次處理
    大量影像可分批處理,每批處理完成釋放記憶體。
  3. 監控記憶體
    psutil 實時檢查記憶體狀況。
  4. 避免不必要的拷貝
    使用 NumPy 的原地操作可以減少額外記憶體消耗。


留言
avatar-img
留言分享你的想法!
avatar-img
螃蟹_crab的沙龍
153會員
297內容數
本業是影像辨識軟體開發,閒暇時間進修AI相關內容,將學習到的內容寫成文章分享。 興趣是攝影,踏青,探索未知領域。 人生就是不斷的挑戰及自我認清,希望老了躺在床上不會後悔自己什麼都沒做。
螃蟹_crab的沙龍的其他內容
2025/01/01
錯誤訊息 Makefile:221: *** found no data/foo-ground-truth/*.gt.txt for data/foo/all-gt. Stop. 原先指令 ALL_FILES = $(and $(wildcard $(GROUND_TRUTH_DIR)),$
Thumbnail
2025/01/01
錯誤訊息 Makefile:221: *** found no data/foo-ground-truth/*.gt.txt for data/foo/all-gt. Stop. 原先指令 ALL_FILES = $(and $(wildcard $(GROUND_TRUTH_DIR)),$
Thumbnail
2024/10/12
在有次使用cv2.resize時忽然報錯,就心血來潮不想重新安裝OpenCV,根據缺少的東西想辦法補齊。 在影像處理中,Zlib(以及 zlibwapi.dll)主要用於處理數據壓縮和解壓縮,特別是在處理大型影像文件時。 遺失原因 應用程序安裝過程中未能完整安裝所有所需的依賴項,尤其是 zli
Thumbnail
2024/10/12
在有次使用cv2.resize時忽然報錯,就心血來潮不想重新安裝OpenCV,根據缺少的東西想辦法補齊。 在影像處理中,Zlib(以及 zlibwapi.dll)主要用於處理數據壓縮和解壓縮,特別是在處理大型影像文件時。 遺失原因 應用程序安裝過程中未能完整安裝所有所需的依賴項,尤其是 zli
Thumbnail
2024/10/11
在上一篇文章,使用CUDA加速運行OpenCV發現一個異常,抽絲剝繭找到原因了。 [Python]在 OpenCV 中啟用 CUDA 加速來運行 DNN 超分辨率模型 錯誤描述: Could not locate cublas64_11.dll. Please make sure it i
Thumbnail
2024/10/11
在上一篇文章,使用CUDA加速運行OpenCV發現一個異常,抽絲剝繭找到原因了。 [Python]在 OpenCV 中啟用 CUDA 加速來運行 DNN 超分辨率模型 錯誤描述: Could not locate cublas64_11.dll. Please make sure it i
Thumbnail
看更多
你可能也想看
Thumbnail
透過蝦皮分潤計畫,輕鬆賺取零用金!本文分享5-6月實測心得,包含數據流程、實際收入、平臺優點及注意事項,並推薦高分潤商品,教你如何運用空閒時間創造被動收入。
Thumbnail
透過蝦皮分潤計畫,輕鬆賺取零用金!本文分享5-6月實測心得,包含數據流程、實際收入、平臺優點及注意事項,並推薦高分潤商品,教你如何運用空閒時間創造被動收入。
Thumbnail
單身的人有些會養寵物,而我養植物。畢竟寵物離世會傷心,植物沒養好再接再厲就好了~(笑)
Thumbnail
單身的人有些會養寵物,而我養植物。畢竟寵物離世會傷心,植物沒養好再接再厲就好了~(笑)
Thumbnail
不知你有沒有過這種經驗?衛生紙只剩最後一包、洗衣精倒不出來,或電池突然沒電。這次一次補貨,從電池、衛生紙到洗衣精,還順便分享使用心得。更棒的是,搭配蝦皮分潤計畫,愛用品不僅自己用得安心,分享給朋友還能賺回饋。立即使用推薦碼 X5Q344E,輕鬆上手,隨時隨地賺取分潤!
Thumbnail
不知你有沒有過這種經驗?衛生紙只剩最後一包、洗衣精倒不出來,或電池突然沒電。這次一次補貨,從電池、衛生紙到洗衣精,還順便分享使用心得。更棒的是,搭配蝦皮分潤計畫,愛用品不僅自己用得安心,分享給朋友還能賺回饋。立即使用推薦碼 X5Q344E,輕鬆上手,隨時隨地賺取分潤!
Thumbnail
身為一個典型的社畜,上班時間被會議、進度、KPI 塞得滿滿,下班後只想要找一個能夠安靜喘口氣的小角落。對我來說,畫畫就是那個屬於自己的小樹洞。無論是胡亂塗鴉,還是慢慢描繪喜歡的插畫人物,那個專注在筆觸和色彩的過程,就像在幫心靈按摩一樣,讓緊繃的神經慢慢鬆開。
Thumbnail
身為一個典型的社畜,上班時間被會議、進度、KPI 塞得滿滿,下班後只想要找一個能夠安靜喘口氣的小角落。對我來說,畫畫就是那個屬於自己的小樹洞。無論是胡亂塗鴉,還是慢慢描繪喜歡的插畫人物,那個專注在筆觸和色彩的過程,就像在幫心靈按摩一樣,讓緊繃的神經慢慢鬆開。
Thumbnail
Python資料視覺化在數據分析中扮演關鍵角色,透過視覺化捕捉數據模式、趨勢和異常,透過Matplotlib等工具創建專業圖表變相對簡單和高效。
Thumbnail
Python資料視覺化在數據分析中扮演關鍵角色,透過視覺化捕捉數據模式、趨勢和異常,透過Matplotlib等工具創建專業圖表變相對簡單和高效。
Thumbnail
對於程式卡頓的問題,如何分析程式碼占用多少記憶體,如何釋放或改寫,可以先用python內建的tracemalloc模組來追蹤 Python 分配的記憶體區塊。 本文將介紹最簡單的用法,來分析一段程式碼占用了多少記憶體。 結果呈現 印出當前使用的記憶體,與峰值記憶體使用量。 程式範例 i
Thumbnail
對於程式卡頓的問題,如何分析程式碼占用多少記憶體,如何釋放或改寫,可以先用python內建的tracemalloc模組來追蹤 Python 分配的記憶體區塊。 本文將介紹最簡單的用法,來分析一段程式碼占用了多少記憶體。 結果呈現 印出當前使用的記憶體,與峰值記憶體使用量。 程式範例 i
Thumbnail
在影像處理中,有時候我們只想特別關注某個感興趣的區域時,就是ROI的概念,擷取此範圍的圖像來做處理。 設定超過圖像邊界時就會報錯,本文主要介紹如何擷取影像的同時,避免設定錯誤造成程式崩潰的狀況。 擷取圖像示意圖 ROI程式範例 import cv2 import numpy as np
Thumbnail
在影像處理中,有時候我們只想特別關注某個感興趣的區域時,就是ROI的概念,擷取此範圍的圖像來做處理。 設定超過圖像邊界時就會報錯,本文主要介紹如何擷取影像的同時,避免設定錯誤造成程式崩潰的狀況。 擷取圖像示意圖 ROI程式範例 import cv2 import numpy as np
Thumbnail
在讀取檔案時,最怕路徑的問題,常常會有路徑錯誤造成的異常報錯。 為了避免諸如此類的問題發生,明白程式的當前目錄與檔案的路徑是很重要的。 可以利用os 模組是 Python 中的一個標準庫,提供了許多與操作系統的功能。 以下是一些常用的 os 模組基本操作及其範例: 1. os.getcwd
Thumbnail
在讀取檔案時,最怕路徑的問題,常常會有路徑錯誤造成的異常報錯。 為了避免諸如此類的問題發生,明白程式的當前目錄與檔案的路徑是很重要的。 可以利用os 模組是 Python 中的一個標準庫,提供了許多與操作系統的功能。 以下是一些常用的 os 模組基本操作及其範例: 1. os.getcwd
Thumbnail
在實務上,若Python報錯時,若引入的套件越多伴隨的異常訊息會變得越來越複雜,看到一推密密麻麻的內容時,很多時候都想直接跳過。 本文將利用Traceback來讓異常訊息變得更好理解。
Thumbnail
在實務上,若Python報錯時,若引入的套件越多伴隨的異常訊息會變得越來越複雜,看到一推密密麻麻的內容時,很多時候都想直接跳過。 本文將利用Traceback來讓異常訊息變得更好理解。
Thumbnail
本文在介紹如何用Python繪製各點大小不同的散布圖及用箭頭標註特殊點
Thumbnail
本文在介紹如何用Python繪製各點大小不同的散布圖及用箭頭標註特殊點
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News