Mempersiapkan Format Image di Deep Learning. Secara umum format yang digunakan yaitu urutan NCHW. Format ini adalah akronim yang menjelaskan urutan sumbu pada tensor yang berisi sampel data gambar. Format NCHW digunakan seperti pada pelatihan di Pytorch. NCHW yaitu N : Jumlah sampel data; C: Saluran gambar. Gambar merah-hijau-biru (RGB) akan memiliki 3 saluran; H: Tinggi gambar; W: Lebar gambar.
Format NCHW merupakan format yang digunakan untuk operasi convolution yang merupakan core nya deep learning, semoga dengan penjelasan artikel dibawah ini memudahkan kalian pengguna library opencv ataupun pillow.
Library Digital Image Processing
Contents
Saat ini biasanya library yang bisa kalian gunakan untuk image seperti opencv ataupun Pillow. Untuk saat ini saya lebih suka menggunakan OpenCV sebagai pra pengolahan. Adapun ada sedikit perbedaan dalam menyajikan array bila menggunakan OpenCV dan Pillow. Misalkan saja untuk opencv akan menyajikan dalam urutan HWC sedangkan untuk Pillow yaitu WH saja. Walaupun begitu nanti kita langsung bisa menggunakan transform yang akan secara otomatis mempunyai urutan CHW serta mengubah nilai pixel opencv uint8 menjadi format float dengan range 0 sampai 1
Perhatikan gambar berikut yang mempunyai tinggi dan lebar yaitu 852 dan 480
Mari kita baca dengan library opencv dan Pillow
import cv2 from PIL import Image from matplotlib import pyplot as plt import torchvision.transforms as transforms
kita loading
file = 'kucing.jpg' img = cv2.imread(file,1) img2 = Image.open(file).convert('RGB')
kita lihat berapa ukurannya masing-masing
print(img.shape) # format HW print(img2.size) # format WH
hasilnya mempunyai cara kerja penyajian yang berbeda
(852, 480, 3) (480, 852)
juga range yang digunakan, untuk
- opencv menggunakan uint8 yaitu 0 sampai 255
- sedangkan pillow menggunakan float yaitu 0 sampai 1
Transform.toTensor() untuk mengubah format menjadi CHW
Sekarang kita akan ubah formatnya menjadi CHW menggunakan transform
transform = transforms.Compose([transforms.ToTensor()]) torch1 = transform(img) # format menjadi CWH torch2 = transform(img2) # idem
mari kita cek, apakah sudah betul urutannya?
print(torch1.shape) print(torch2.shape)
hasilnya
torch.Size([3, 1837, 1297]) torch.Size([3, 1837, 1297])
unsqueeze untuk mengubah format menjadi NCHW
Kita akan ubah menjadi format NCHW
batch1 = torch1.unsqueeze(0) # menjadi NCHW batch2 = torch2.unsqueeze(0) # menjadi NCHW
mari kita cek
print(batch1.shape) print(batch2.shape)
hasilnya
torch.Size([1, 3, 1837, 1297]) torch.Size([1, 3, 1837, 1297])
kalian bisa melihat hasilnya akan sama format dengan ukurannya!
squeeze untuk mengubah kembali ke format CHW
Mari kita akan ubah lagi ke CHW agar bisa ditampilkan ke matplotlib, kalian bisa menggunakan function transforms.ToPILImage()(batch1.squeeze(0)
plt.figure() plt.subplot(1,2,1),plt.imshow(transforms.ToPILImage()(batch1.squeeze(0))) plt.subplot(1,2,2),plt.imshow(transforms.ToPILImage()(batch2.squeeze(0))) plt.show()
tapi kok beda ya!
Yup hal ini dikarenakan adannya perbedaan cara menyajikan format warna yaitu
- opencv menggunakan format BGR
- sedangkan Pillow dan Matplotlib menggunakan format RGB
Format BGR dan RGB
Yup karena pada dasarnya opencv menggunakan format BGR ketika loading secara default, oleh hal tersebut kalian ubah terlebih dahulu diawal menjadi berikut menggunakan function cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
file = 'kucing.jpg' img = cv2.imread(file,1) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img2 = Image.open(file).convert('RGB')
kemudian ulangi run dari awal maka hasilnya akan sama!
Range warna 0 sampai 255 menjadi 0 sampai 1
Seperti yang sudah saya jelaskan bahwa range warna opencv menggunakan uint8 dengan skala 0 sampai 255, mari kita cek
img
hasilnya
array([[[234, 200, 41], [234, 200, 41], [234, 200, 41], ..., [232, 196, 24], [232, 196, 24], [232, 196, 24]], [[234, 200, 41], [234, 200, 41], [234, 200, 41], ..., [232, 196, 24], [232, 196, 24], [232, 196, 24]], [[235, 199, 41], [235, 199, 41], [235, 199, 41], ..., [232, 196, 24], [232, 196, 24], [232, 196, 24]], ..., [[251, 230, 137], [251, 230, 137], [251, 230, 139], ..., [247, 222, 104], [246, 221, 103], [246, 221, 103]], [[251, 230, 137], [251, 230, 137], [251, 230, 139], ..., [247, 222, 104], [247, 222, 104], [246, 221, 103]], [[251, 230, 137], [251, 230, 137], [251, 230, 139], ..., [248, 223, 105], [247, 222, 104], [247, 222, 104]]], dtype=uint8)
akan tetapi akan berubah otomatis menjadi skala 0 sampai 1 ketika kita panggil function transform yang akan mengubah array menjadi tensor float skala 0 sampai 1
transform = transforms.Compose([transforms.ToTensor()]) torch1 = transform(img) # format menjadi CWH
jadi kalian tidak perlu secara manual melakukan teknik normalisasi lagi.
Kalian bisa cek kok antar batch1 dan batch2 mempunyai isi/value pixel yang sama!
Mengubah Tensor -> Pillow -> OpenCV
untuk mengubah kembali kedalam bentuk opencv, kalian bisa menggunakan cara berikut
import numpy as np img3 = np.array(transforms.ToPILImage()(batch1.squeeze(0))) print(img3.shape)
Kita bisa cek hasilnya akan sama seperti semula
dan nilanya akan kembali seperti semula dengan range 0 sampai 255 lagi
Kesimpulan
Berikut kesimpulan yang didapatkan
- Format CNWH merupakan format standar yang digunakan untuk pytorch.
- Float dengan skala 0 sampai 1 (float) merupakan nilai yang akan digunakan tensor di pytorch.
- Fungsi yang sering digunakan yaitu
- transforms.ToTensor() mengubah HW/WH menjadi CHW
- .unsqueeze(0) mengubah CHW menjadi NCHW
- .squeeze(0) mengubah NCHW menjadi CHW