2024-09-04|閱讀時間 ‧ 約 22 分鐘

[Python][OpenCV]使用yield應用在影像讀取的好處

yield 在影像處理中也是蠻好用的,特別是當你需要處理大量影像或希望逐步處理影像時。它可以用來生成一個影像流,讓你能夠一次處理一張影像而不需要一次性加載所有影像進記憶體。

yield 是 Python 中的一個關鍵字,用於創建生成器(generator)。

生成器是一種特殊類型的迭代器,允許你逐步生成序列中的值而不是一次性返回整個序列。這種延遲生成的特性對於處理大量數據或需要逐步處理數據的情況非常有用。

本文將比較yield與List儲存影像,所佔用的記憶體大小,來體現使用yield有什麼實質上的好處。


使用yield方法:

import cv2
import os
import numpy as np

def is_ndarray(variable):
return isinstance(variable, np.ndarray)

def process_images_in_directory(directory):
for filename in os.listdir(directory):
if filename.endswith(('.png', '.jpg', '.jpeg', '.bmp')):
img_path = os.path.join(directory, filename)
img = cv2.imdecode(np.fromfile(file=img_path, dtype=np.uint8), cv2.IMREAD_COLOR)

if img is None:
continue
# 進行影像處理,例如轉換為灰階
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 使用 yield 返回處理後的影像
yield gray_img, filename

directory_path = 'D:/crab/照片/寶貝狗狗'
img_generator = process_images_in_directory(directory_path)
for gray_img, filename in img_generator:
# 這裡可以進一步處理影像或顯示影像
if is_ndarray(gray_img):
print(gray_img.shape)
cv2.imshow('Gray_Image', gray_img)
cv2.waitKey(0) # 按任意鍵繼續
cv2.destroyAllWindows()

使用列表儲存影像

將所有影像讀取後存到一個列表中,然後進行後續處理:

import cv2
import os
import numpy as np

def process_images_in_directory(directory):
images = []
filenames = []
for filename in os.listdir(directory):
if filename.endswith(('.png', '.jpg', '.jpeg', '.bmp')):
img_path = os.path.join(directory, filename)
img = cv2.imdecode(np.fromfile(file=img_path, dtype=np.uint8), cv2.IMREAD_COLOR)

if img is None:
continue

# 進行影像處理,例如轉換為灰階
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

images.append(gray_img)
filenames.append(filename)

return images, filenames

directory_path = 'D:/crab/照片/寶貝狗狗'
images, filenames = process_images_in_directory(directory_path)

for gray_img, filename in zip(images, filenames):
if is_ndarray(gray_img):
print(f"{filename} 的形狀: {gray_img.shape}")
cv2.imshow('Gray_Image', gray_img)
cv2.waitKey(0) # 按任意鍵繼續
cv2.destroyAllWindows()

結論

但兩種方法,使用tracemalloc來分析佔用的記憶體大小,使用yield的方法比較省記憶體


tracemalloc其他文章
[Python]使用tracemalloc 模組來比較兩種不同方法所佔用的記憶體大小



分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.