
Secara umum kita mengenal dataset image processing di pytorch menggunakan Pillow. Pillow menggunakan format yang tersusun agak beda dengan Opencv. Untuk Pillow menggunakan format WH sedangkan opencv dengan HW. Perbedaan cukup serius jika tidak dipahami dengan benar karena format Pytorch menggunakan NCHW. N merupakan batch, C adalah channel, H adalah height, dan W adalah width.
Mengenal Format NCHW pada Pytorch
Contents
Pembahasan mengenai format tersebut bisa kalian baca di Mempersiapkan Format Image di Deep Learning. Adakalanya kita tidak menggunakan Pillow karena function computer vision yang lengkap ada di OpenCV. Biasanya saya lebih suka menggunakan OpenCV daripada Pillow. Secara default ketika menggunakan Pillow, kita butuh transform untuk mengubah format WH pillow menjadi CHW sebelum nanti dimasukan ke Loader menjadi format NCHW (atau kalau single file) bisa menggunakan perintah
- .unsqueeze(0) mengubah CHW menjadi NCHW
- .squeeze(0) mengubah NCHW menjadi CHW
Transform
Digunakan untuk Memproses dan mempersiapkan data (biasanya gambar) sebelum dikirim ke model. Kenapa Penting? Model deep learning tidak bisa langsung membaca gambar mentah (misalnya hasil cv2.imread()
atau PIL.Image
) — perlu diubah dulu ke format tensor, dinormalisasi, diubah ukurannya, dll.
Contoh transform secara umum
from torchvision import transforms transform = transforms.Compose([ transforms.Resize((224, 224)), # ubah ukuran gambar transforms.Grayscale(), # ubah ke grayscale transforms.ToTensor(), # ubah ke tensor (0–1, CHW) transforms.Normalize(mean=[0.5], std=[0.5]) # normalisasi ke [-1, 1] ])
Untuk mempermudah permahaman, saya gunakan kode yang lebih simple saja untuk mengetahui cara penanganan Pillow dan OpenCV pada Transform menggunakan kode simple transform dibawah ini
from torchvision import transforms transform = transforms.Compose([ transforms.Grayscale(), # Convert ke grayscale transforms.ToTensor(), # Terakhir ubah ke tensor ])
Pillow
Pillow adalah library Python untuk memproses dan memanipulasi gambar. Ini adalah versi modern dari PIL (Python Imaging Library), yang dulu sempat tidak dikembangkan lagi. Berikut contoh function dasar pada Pillow
Fungsi | Contoh |
---|---|
Membuka gambar | Image.open("gambar.jpg") |
Menyimpan gambar | img.save("output.png") |
Mengubah ukuran | img.resize((224, 224)) |
Mengubah format | img.convert("L") → grayscale, "RGB" , "RGBA" dll |
Rotate / flip | img.rotate(90) atau img.transpose(Image.FLIP_LEFT_RIGHT) |
Crop | img.crop((x1, y1, x2, y2)) |
Contoh singkat penggunaan Pillow
from PIL import Image # Buka gambar img = Image.open("gambar.jpg") # Ubah ke grayscale gray = img.convert("L") # Resize resized = gray.resize((128, 128)) # Simpan hasil resized.save("gray_128x128.png")
Kenapa Pillow Penting untuk PyTorch?
Karena:
-
Banyak transform di
torchvision.transforms
butuh input gambar berupa PIL.Image, bukan NumPy array. -
Jadi kalau kamu pakai
cv2
(yang hasilnya NumPy), kamu harus konversi ke PIL:
Mengapa pytorch memilih Pillow daripada OpenCV sebagai default penggunaannya?
Karena Pillow lebih sederhana, ringan, dan lebih “Pythonic”, serta sudah cukup untuk banyak keperluan pre-processing gambar sebelum dikirim ke model.
- Format default
- Pillow: warna RGB (cocok untuk deep learning)
- OpenCV: BGR (sering bikin bingung 😅)
- Integrasi dengan PyTorch
- Pillow: Sangat kompatibel dengan torchvision.transforms
- OpenCV: Perlu konversi NumPy → PIL sebelum transform
- Sederhana untuk loading
- Pillow: Image.open(…) → langsung jadi PIL image
- OpenCV: cv2.imread(…) hasilnya NumPy array
- Ukuran library
- Pillow: Lebih kecil
- OpenCV: Lebih besar, banyak dependensi (C++, GUI, dll)
- Kecepatan Cukup
- Pillow: cepat untuk tugas ringan
- OpenCV: Lebih cepat untuk pemrosesan video / real-time
- Komunitas
- Pillow: PyTorch Sudah terbiasa dengan PIL
- OpenCV: Perlu effort ekstra untuk integrasi
- Transform (rotate, resize)
- Pillow: Terintegrasi langsung di torchvision.transforms
- OpenCV: Harus pakai cv2.resize, cv2.rotate, dll
Kita akan uji coba loading gambar dengan ukuran
- H height: 254, dan
- W width: 199, kita akan loading via Pillow
from PIL import Image img = Image.open("cat.jpeg").convert("RGB") img.size
dengan output yaitu
(199, 254)
yang artinya Pillow dengan format urutan WH, langkah selanjutnya transform yang akan mengubah menjadi CHW
img_tensor = transform(img) img_tensor.shape
hasilnya format berubah menjadi CHW
torch.Size([1, 254, 199])
kemudian untuk mengubah ke format NCHW menggunakan perintah berikut
img_tensor.unsqueeze(0).shape
hasilnya
torch.Size([1, 1, 254, 199])
OpenCV
mari kita akan loading gambar dengan OpenCV
import cv2 img_numpy = cv2.imread('cat.jpeg',0) img_numpy.shape
dengan format HW
(254, 199)
Apa yang terjadi ketika kita panggil
img_numpy_tensor = transform(img_numpy)
pasti akan terjadi error!
TypeError: img should be PIL Image. Got <class 'numpy.ndarray'>
untuk mengatasi hal tersebut, kita butuh konvert Image.fromarray() sehingga secara otomatis akan mengubah juga skala nya dari semula 0 sd 255 menjadi 0 sd 1
transform(Image.fromarray(img_numpy)).shape
sekalian cek hasilnya
torch.Size([1, 254, 199])
Mengapa langsung menggunakan transform dengan input numpy mengalami error? Karena transformasi seperti transforms.Grayscale()
dan transforms.ToTensor()
dari torchvision
:
-
Hanya menerima input berupa objek PIL Image, bukan NumPy array.
-
Didesain untuk dipakai dengan
PIL.Image.open()
atau dataset sepertiImageFolder
.
Sehingga kode nya sebagai berikut
transform(Image.fromarray(img_numpy))
Sekedar informasi mengenai format NCHW
Huruf | Arti | Penjelasan |
---|---|---|
N | Batch Size | Jumlah gambar dalam satu batch |
C | Channels | Jumlah channel (1 = grayscale, 3 = RGB) |
H | Height | Tinggi gambar |
W | Width | Lebar gambar |
Format Alternatif: NHWC
Framework lain seperti TensorFlow kadang pakai format NHWC
:
-
N = batch
-
H = height
-
W = width
-
C = channels
Format tersebut ada di Tensorflow