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
螃蟹_crab的沙龍
158會員
310內容數
本業是影像辨識軟體開發,閒暇時間進修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
我每週都會為自己設計一趟小旅行,像是給日常的一個深呼吸。準備著簡單的行李,在導航上設定好今天想去的地方,播放一張剛好符合心情的歌單,一場逃離日常的小旅行就此展開。 說走就走的自由很浪漫,但背後的現實是,從加油、路途中補給、到抵達目的地的小花費,每一筆都需要精打細算,才能不讓放鬆變成負擔。好在有玉山
Thumbnail
我每週都會為自己設計一趟小旅行,像是給日常的一個深呼吸。準備著簡單的行李,在導航上設定好今天想去的地方,播放一張剛好符合心情的歌單,一場逃離日常的小旅行就此展開。 說走就走的自由很浪漫,但背後的現實是,從加油、路途中補給、到抵達目的地的小花費,每一筆都需要精打細算,才能不讓放鬆變成負擔。好在有玉山
Thumbnail
本文介紹玉山銀行推出的玉山 Unicard,是一張非常符合「小資族、學生、上班族都好上手」的高回饋信用卡!三種回饋方案自由切換,行動支付、百貨、旅遊、百大指定通路全面涵蓋,新戶最高享 7.5% 回饋。回饋透明、操作簡單,非常推薦學生、小資族與上班族。
Thumbnail
本文介紹玉山銀行推出的玉山 Unicard,是一張非常符合「小資族、學生、上班族都好上手」的高回饋信用卡!三種回饋方案自由切換,行動支付、百貨、旅遊、百大指定通路全面涵蓋,新戶最高享 7.5% 回饋。回饋透明、操作簡單,非常推薦學生、小資族與上班族。
Thumbnail
信用卡如今已是現代人日常消費的必需品。回顧其誕生,竟源於一段用餐忘記帶錢的窘境。本文將帶您瞭解信用卡的故事,並介紹「玉山Unicard」,一張涵蓋百大通路、提供彈性回饋的信用卡,尤其適合追求方便與高回饋的消費者。文章將分享誠品生活、全盈+PAY等實際使用情境,並提供新戶申辦優惠資訊。
Thumbnail
信用卡如今已是現代人日常消費的必需品。回顧其誕生,竟源於一段用餐忘記帶錢的窘境。本文將帶您瞭解信用卡的故事,並介紹「玉山Unicard」,一張涵蓋百大通路、提供彈性回饋的信用卡,尤其適合追求方便與高回饋的消費者。文章將分享誠品生活、全盈+PAY等實際使用情境,並提供新戶申辦優惠資訊。
Thumbnail
玉山銀行新推出的Unicard信用卡你發現了嗎?主打可透過玉山Wallet App,每月自由切換簡單選、任意選及UP選三種方案,讓你依照消費習慣擁有不同的回饋方案。其中我自己很喜歡它百大指定消費中的Line Pay行動支付,能讓我以最簡單的方式獲得最高的回饋!同時文中更分享我實測的眉角,快來看下去!
Thumbnail
玉山銀行新推出的Unicard信用卡你發現了嗎?主打可透過玉山Wallet App,每月自由切換簡單選、任意選及UP選三種方案,讓你依照消費習慣擁有不同的回饋方案。其中我自己很喜歡它百大指定消費中的Line Pay行動支付,能讓我以最簡單的方式獲得最高的回饋!同時文中更分享我實測的眉角,快來看下去!
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