前幾天我們認識了 Pixel、RGB 與 Channel,也知道對電腦來說,一張圖片其實就是由大量數值組成的資料
但在真正把圖片交給模型之前,通常還需要先經過一些處理,例如調整圖片大小、裁切特定區域等
而圖片一旦經過處理,電腦能取得的影像資訊也可能跟著改變,我們可以先從一個生活中的例子來想像:

左邊是一張正常的貓咪圖片,我們可以清楚看到牠的眼睛、毛髮、耳朵等細節;但右邊的貓咪隔著方格玻璃後,畫面被切成一格一格,許多原本清楚的細節也跟著消失了,雖然我們還是可以認出「這是一隻貓」,但可以發現:圖片保留下來的細節越少,我們能取得的影像資訊也會跟著減少
當然,方格玻璃造成的效果和電腦的圖片縮放並不完全相同,不過它可以幫助我們想像:當影像細節減少時,有些原本清楚的特徵也可能變得不明顯
對一般照片來說,少掉一些細節可能沒有太大影響;但如果今天處理的是皮膚病灶影像,一些細微的顏色、紋理或邊界,都可能是值得保留的資訊,所以今天我們就從最基本的三個影像操作開始:
讀取(Read)、縮放(Resize)與裁切(Crop)
我們先使用 Python 的 PIL 讀取 HAM10000 中的一張圖片:
from PIL import Image
import matplotlib.pyplot as plt
img = Image.open(image_path)
plt.imshow(img)
plt.axis("off")
plt.show()
print("圖片尺寸:", img.size)
其中 Image.open(image_path) 就是根據圖片的路徑,把圖片讀進 Python
而 img.size 可以查看圖片大小
以我們前面使用的 HAM10000 圖片為例,(600, 450) 代表Width = 600 Pixel、Height = 450 Pixel,所以讀取圖片其實就是讓 Python 能夠取得圖片中的 Pixel 資訊,之後我們才能繼續進行處理
假設我們現在有兩張圖片:
圖片 A 是 600 × 450
圖片 B 是 800 × 600
如果之後要一次將很多圖片交給模型訓練,圖片尺寸不一致就會很麻煩,因此通常會先把所有圖片調整成相同大小,這個動作就是 Resize(縮放),使用 PIL 可以直接:
resized_img = img.resize((224, 224))
print("原始尺寸:", img.size)
print("縮放後尺寸:", resized_img.size)
plt.imshow(resized_img)
plt.axis("off")
plt.show()
結果會從 600 × 450 變成 224 × 224
但縮小圖片不會損失資訊嗎?
答案是:會,試想:
原本有:600 × 450 = 270,000 Pixel
縮小成:224 × 224 = 50,176 Pixel
代表電腦需要用更少的 Pixel 表示原本的圖片,因此一定會損失部分細節,不過圖片越大,需要處理的資料也越多,模型訓練需要的記憶體與運算量也會增加,所以之後在訓練模型時,圖片尺寸其實也是一個需要考量的參數
Resize 是把整張圖片改變大小,Crop 則不一樣,Crop 是從原本的圖片中,只取出其中一個區域,就可以使用:
cropped_img = img.crop((150, 75, 450, 375))
plt.imshow(cropped_img)
plt.axis("off")
plt.show()
這四個數字 (150, 75, 450, 375) 代表 (left, top, right, bottom),電腦會根據定義把這個範圍內的圖片取出來
讀取、縮放和裁切看起來只是很基本的圖片操作,但它們其實會直接影響電腦最後能從圖片中取得多少資訊
例如,將圖片縮小可以統一圖片尺寸,也能減少需要處理的 Pixel 數量,讓後續模型訓練更有效率;但如果圖片縮得太小,一些細微的紋理、顏色或邊界也可能跟著消失
裁切也是一樣,適當的裁切可以減少不需要的背景,讓我們更專注在重要的區域;但如果裁切範圍不適當,也可能把重要的影像資訊一起移除
下一篇我們更進一步進入 Image Preprocessing(影像前處理),看看為什麼圖片在交給模型之前,還需要進行數值上的處理