Pengolahan Citra · Materi 03

Color Space dan Manipulasi Warna

Mengubah BGR/RGB/grayscale/HSV, memisahkan channel, dan mendeteksi objek merah, hijau, serta biru melalui mask HSV.

Google Colab · OpenCV · Pemahaman konsep → pengamatan → praktikum → analisis

Mode belajar: tulis kode sendiri. Copy/cut, seleksi teks dan klik kanan dibatasi pada halaman; pembatasan UI bukan jaminan anti-penyalinan mutlak.

1. Tujuan

  1. Mengonversi gambar BGR menjadi RGB, grayscale, dan HSV menggunakan flag yang tepat.
  2. Memisahkan channel warna dan menjelaskan arti setiap channel serta rentang HSV uint8 OpenCV.
  3. Membangun mask satu warna dengan inRange dan menampilkan objek hasil masking.
  4. Mendeteksi merah, hijau, dan biru dengan batas HSV terdokumentasi serta menjelaskan kegagalannya.

Prasyarat: Dapat upload dan membaca gambar di Google Colab serta memahami indeks array, pixel, dan channel. Sel pada modul ini tetap lengkap dan mandiri.

2. Materi Pembahasan

Mask warna menghasilkan kandidat area; tidak menjamin identitas objek daun.
Mask warna menghasilkan kandidat area; tidak menjamin identitas objek daun.

2.1 Ruang warna dan urutan komponen

Ruang warna menyediakan cara menyatakan warna sebagai komponen numerik. BGR dan RGB memuat komponen warna dasar yang sama, tetapi urutannya berbeda. Array hasil pembacaan OpenCV harus dikonversi ke RGB sebelum ditampilkan dengan Matplotlib. Menukar urutan komponen tidak mengubah lokasi pixel atau menambah informasi gambar; yang berubah adalah cara komponen tersebut ditafsirkan. Periksa warna objek yang sudah diketahui untuk menghindari analisis berdasarkan tampilan yang tertukar.

Konversi ke grayscale menghasilkan intensitas tunggal dengan kontribusi berbobot dari komponen warna. Karena warna berbeda dapat memiliki intensitas serupa, grayscale tidak cukup untuk semua tugas segmentasi warna. Dalam praktikum, simpan bgr sebagai sumber dan buat variabel rgb, gray, serta hsv terpisah. Kebiasaan ini mencegah array HSV secara tidak sengaja diperlakukan sebagai foto RGB.

2.2 Membaca channel secara terpisah

Pemecahan channel memakai cv2.split sehingga komponen B, G, dan R dapat diperiksa satu per satu. Tampilan grayscale dari channel R menunjukkan seberapa kuat komponen merah di setiap lokasi, bukan gambar yang hanya memuat objek berwarna merah. Objek putih dapat terang pada semua channel, sedangkan objek merah yang gelap mungkin memiliki komponen merah kecil. Karena itu satu channel saja tidak selalu menghasilkan pemisahan warna yang bersih.

Hal serupa berlaku untuk HSV. Channel H menunjukkan keluarga warna, S menunjukkan kejenuhan, dan V menunjukkan nilai kecerahan representasinya. Tampilkan ketiganya sebagai peta scalar dengan judul dan rentang yang benar. Tampilan array HSV langsung sebagai RGB menghasilkan warna semu yang tidak menggambarkan foto asli. Bandingkan peta channel dengan foto sumber untuk menghubungkan angka dengan lokasi objek dan latar.

2.3 HSV untuk keputusan berbasis warna

HSV memisahkan hue dari kejenuhan dan value sehingga aturan deteksi warna lebih mudah dijelaskan. Untuk input uint8 dan COLOR_BGR2HSV, hue memiliki rentang 0–179, sementara S dan V berada pada 0–255. Rentang ini bukan derajat 0–360 yang digunakan beberapa aplikasi lain. Contoh menggunakan rentang awal hijau 35–85 dan biru 90–130, disertai batas minimum S serta V untuk membatasi pixel sangat pucat atau sangat gelap.

Batas tersebut merupakan parameter awal, bukan standar universal warna semua kamera. Pencahayaan, white balance, refleksi, dan kompresi dapat menggeser nilai. Hue pada daerah hampir abu-abu juga tidak stabil sebagai indikator warna. Memilih batas S dan V membantu, tetapi dapat membuang objek yang pucat atau berbayang. Jelaskan kompromi ini ketika menilai mask kosong, objek terpotong, atau background ikut terambil.

2.4 Mask biner dan ekstraksi objek

cv2.inRange menghasilkan mask satu channel berisi 255 untuk pixel yang memenuhi semua batas komponen dan 0 untuk sisanya. Mask bukan foto baru yang berwarna; ia menyatakan lokasi yang dipilih. cv2.bitwise_and dengan parameter mask menerapkan keputusan itu pada gambar BGR sumber. Lokasi di luar mask tampil hitam karena nilainya dibuat nol, bukan karena latar asli harus berwarna hitam.

Hue bersifat melingkar, sehingga merah dapat berada dekat 0 maupun ujung atas rentang. Dua mask merah digabung dengan bitwise_or sebelum dipakai untuk ekstraksi. Perhatikan bahwa jumlah pixel terpilih mengukur luas pada gambar, bukan jumlah objek. Beberapa benda terpisah dengan warna sama tetap masuk satu mask, dan satu benda yang memantulkan warna berbeda dapat hanya terdeteksi sebagian.

2.5 Kalibrasi dan pelaporan yang jujur

Praktikum dimulai dengan satu foto objek berwarna yang jelas dan background tidak serupa. Pemeriksaan titik tengah pada contoh memberi nilai BGR serta HSV, tetapi titik itu tidak dijamin berada pada objek. Untuk kalibrasi, mahasiswa memilih koordinat yang benar-benar berada di permukaan objek dan membandingkan beberapa lokasi terang maupun berbayang. Ubah interval sesuai observasi sambil mencatat batas awal dan batas akhir.

Pada tugas, gunakan foto yang memuat merah, hijau, dan biru, atau jalankan notebook pada tiga foto terpisah dengan output tetap terlihat. Selalu tampilkan foto sumber, mask, dan hasil ekstraksi setiap warna. Jika suatu warna tidak ada, mask kosong adalah hasil sah; jangan mengklaim objek ditemukan. Nilai keberhasilan didasarkan pada ketepatan lokasi serta keterbatasan metode, bukan semata-mata banyaknya pixel putih.

Video pembelajaran sesuai bab

OpenCV Python Tutorial #5 - Colors and Color Detection — Tech With Tim.

Fokus saat menonton: Amati perbedaan RGB/BGR/HSV serta cara mask memilih rentang warna.

Buka video di YouTube jika pemutar tidak tersedia

Video referensi berbahasa Inggris. Bila ada setup lokal, API atau versi model berbeda, pelajari konsepnya dan tetap gunakan alur Google Colab pada praktikum bab ini. Ketersediaan pemutar mengikuti YouTube, pemilik video dan jaringan.

Referensi dan sumber ilustrasi

Foto daun: Ανώνυμος Βικιπαιδιστής, Wikimedia Commons, CC BY 3.0; diubah ukuran/intensitas untuk ilustrasi. Foto bus: contoh aset Ultralytics. Foto astronaut: NASA melalui scikit-image. Panel diagram/simulasi ditandai pada caption; bukan hasil eksperimen yang dikarang. Hak penggunaan sumber tetap mengikuti sumber asli.

3. Praktikum Google Colab

Buka Google Colab

Buat notebook baru, simpan pada Drive milik sendiri, lalu isi identitas. Gunakan sel kode terpisah untuk setiap langkah dan jalankan berurutan dengan Shift + Enter. Tidak perlu mengunduh notebook contoh atau memasang Python lokal.

Identitas di bagian paling atas notebook: tambahkan sel Text/Markdown sebelum kode dan isi Nama serta NPM.
# Materi 03 — Pengolahan Citra
Nama: [Nama lengkap mahasiswa]
NPM: [NPM mahasiswa]
Kelas: [Kelas, jika diperlukan]
  1. Buat notebook Colab mandiri dengan Nama dan NPM; ketik import dan upload.
  2. Pilih foto objek berwarna dengan pencahayaan cukup; hindari gambar alpha/transparan.
  3. Jalankan konversi dan pemisahan channel; jelaskan mengapa peta channel bukan foto warna asli.
  4. Jalankan sel deteksi; baca satu baris mask dan hasil ekstraksi terlebih dahulu.
  5. Ambil nilai HSV beberapa pixel objek menggunakan hsv[y, x], kemudian kalibrasi rentang bila perlu.
  6. Untuk tugas, lengkapi deteksi merah, hijau, serta biru dan simpan semua output serta analisis dalam satu notebook.

Sel 1 — 1. Import library

Ketik di notebook Colab baru setelah sel Markdown Nama dan NPM. Modul ini mandiri; tidak menggunakan variabel dari modul lain.

import cv2
import numpy as np
import matplotlib.pyplot as plt
from google.colab import files

Sel 2 — 2. Upload satu foto

Pilih satu foto JPEG/PNG uint8, maksimum 10 MiB dan 12 juta pixel. Pembacaan mempertahankan channel asli untuk validasi, lalu menyiapkan BGR tiga channel. PNG transparan tidak dipakai agar tidak ada background tersembunyi.

uploaded = files.upload()
if len(uploaded) != 1:
    raise ValueError("Pilih tepat satu foto JPEG/PNG.")
nama, data = next(iter(uploaded.items()))
if not nama.lower().endswith((".jpg", ".jpeg", ".png")):
    raise ValueError("Gunakan file JPEG atau PNG.")
if not data or len(data) > 10 * 1024 * 1024:
    raise ValueError("File kosong atau melebihi 10 MiB.")
raw = cv2.imdecode(np.frombuffer(data, np.uint8), cv2.IMREAD_UNCHANGED)
if raw is None:
    raise ValueError("File tidak dapat didecode sebagai gambar.")
h, w = raw.shape[:2]
if h * w > 12_000_000 or min(h, w) < 32 or raw.dtype != np.uint8:
    raise ValueError("Gunakan gambar uint8, sisi minimal 32 pixel, <=12 MP.")
if raw.ndim == 2:
    bgr = cv2.cvtColor(raw, cv2.COLOR_GRAY2BGR)
elif raw.ndim == 3 and raw.shape[2] == 3:
    bgr = raw.copy()
else:
    raise ValueError("Gunakan foto grayscale/3 channel tanpa alpha.")
print("Foto:", nama, "shape BGR:", bgr.shape)
plt.figure(figsize=(6, 5))
plt.imshow(cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB))
plt.title("Foto unggahan")
plt.axis("off")
plt.show()

Sel 3 — 3. Konversi dan inspeksi ruang warna

RGB dipakai untuk tampilan, grayscale untuk intensitas, dan HSV untuk aturan warna. Nilai pixel tengah hanya contoh pembacaan; pilih koordinat objek saat kalibrasi.

rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB)
gray = cv2.cvtColor(bgr, cv2.COLOR_BGR2GRAY)
hsv = cv2.cvtColor(bgr, cv2.COLOR_BGR2HSV)
y, x = bgr.shape[0] // 2, bgr.shape[1] // 2
print("Koordinat (x,y):", (x, y))
print("BGR:", bgr[y, x].tolist(), "RGB:", rgb[y, x].tolist())
print("Gray:", int(gray[y, x]), "HSV:", hsv[y, x].tolist())
fig, ax = plt.subplots(1, 2, figsize=(12, 5))
ax[0].imshow(rgb); ax[0].set_title("RGB: warna asli")
ax[1].imshow(gray, cmap="gray", vmin=0, vmax=255); ax[1].set_title("Grayscale")
for a in ax: a.axis("off")
plt.tight_layout(); plt.show()

Sel 4 — 4. Pisahkan BGR dan HSV

Channel ditampilkan sebagai scalar grayscale; panel R bukan hasil deteksi objek merah. H menggunakan rentang 0–179.

B, G, R = cv2.split(bgr)
H, S, V = cv2.split(hsv)
fig, axes = plt.subplots(2, 3, figsize=(14, 8))
for ax, judul, channel, maksimum in zip(
        axes.flat, ["B", "G", "R", "H", "S", "V"],
        [B, G, R, H, S, V], [255, 255, 255, 179, 255, 255]):
    ax.imshow(channel, cmap="gray", vmin=0, vmax=maksimum)
    ax.set_title(f"Channel {judul} (0–{maksimum})")
    ax.axis("off")
plt.tight_layout(); plt.show()

Sel 5 — 5. Deteksi merah, hijau, dan biru

Contoh lengkap memproses tiga warna sekaligus; fokuskan pembahasan awal pada satu warna objek. Parameter merupakan baseline yang boleh dikalibrasi, bukan jaminan semua foto.

rentang = {
    "merah": [((0, 80, 50), (10, 255, 255)),
              ((170, 80, 50), (179, 255, 255))],
    "hijau": [((35, 60, 40), (85, 255, 255))],
    "biru": [((90, 80, 50), (130, 255, 255))]
}
masks = {}
fig, axes = plt.subplots(3, 3, figsize=(14, 12))
for baris, (warna, interval) in enumerate(rentang.items()):
    mask = np.zeros(hsv.shape[:2], dtype=np.uint8)
    for bawah, atas in interval:
        bagian = cv2.inRange(hsv, np.array(bawah, np.uint8), np.array(atas, np.uint8))
        mask = cv2.bitwise_or(mask, bagian)
    masks[warna] = mask
    hasil = cv2.bitwise_and(bgr, bgr, mask=mask)
    jumlah = int(np.count_nonzero(mask))
    print(warna, "batas:", interval, "pixel terpilih:", jumlah,
          "persen:", round(100 * jumlah / mask.size, 2))
    axes[baris, 0].imshow(rgb); axes[baris, 0].set_title("Foto sumber")
    axes[baris, 1].imshow(mask, cmap="gray", vmin=0, vmax=255)
    axes[baris, 1].set_title(f"Mask {warna}")
    axes[baris, 2].imshow(cv2.cvtColor(hasil, cv2.COLOR_BGR2RGB))
    axes[baris, 2].set_title(f"Ekstraksi {warna}")
    for ax in axes[baris]: ax.axis("off")
    if jumlah == 0:
        print(f"Tidak ada pixel memenuhi rentang {warna}; cek objek dan parameter.")
plt.tight_layout(); plt.show()

Jika terjadi error

Mask kosong meski objek terlihat.
Periksa urutan konversi BGR2HSV, range H 0–179, serta batas S/V; sampel pixel objek dan sesuaikan parameter.
Sebagian objek merah hilang.
Gunakan kedua interval hue merah dan gabungkan mask dengan bitwise_or.
HSV ditampilkan sebagai foto warna yang aneh.
Tampilkan foto dari RGB; pisahkan H/S/V dan gunakan peta scalar untuk memeriksa HSV.
Latar berwarna sama ikut terdeteksi.
Akui batas deteksi warna; ubah latar/pencahayaan atau tambahkan pembatas lokasi dalam pengembangan, bukan mengklaim pengenal objek.

Runtime Colab dan file upload bersifat sementara. Simpan output penting pada notebook/Drive sebelum sesi berakhir. Jika runtime direset, jalankan ulang sel dari awal. Gunakan media berizin dan hindari unggahan data sensitif tanpa izin.

4. Tugas 3

Bangun deteksi objek merah, hijau, dan biru menggunakan HSV. Kumpulkan hanya SATU link Google Colab berakses Viewer, memuat Nama/NPM, kode, output, dan analisis.

Ketentuan pengerjaan

  1. Gunakan foto sendiri yang memuat ketiga warna, atau tiga foto berbeda dalam notebook yang sama.
  2. Tampilkan sumber RGB, grayscale, serta pemisahan channel BGR dan HSV.
  3. Deteksi ketiga warna memakai inRange; merah harus mencakup dua interval hue.
  4. Tampilkan mask dan hasil ekstraksi setiap warna, jumlah pixel, serta batas H/S/V yang dipakai.
  5. Sertakan nilai pixel objek untuk alasan kalibrasi dan satu contoh kegagalan atau keterbatasan.
  6. Simpan seluruh hasil dan analisis dalam satu link Google Colab akses Viewer; tidak ada berkas terpisah.

Pertanyaan analisis

  1. Mengapa batas S/V diperlukan selain hue?
  2. Pada bagian mana mask menghasilkan false positive atau false negative, dan apa penyebabnya?
  3. Mengapa dua rentang merah perlu digabung, dan mengapa luas mask tidak sama dengan jumlah objek?
Identitas di bagian paling atas notebook: tambahkan sel Text/Markdown sebelum kode dan isi Nama serta NPM.
# Materi 03 — Pengolahan Citra
Nama: [Nama lengkap mahasiswa]
NPM: [NPM mahasiswa]
Kelas: [Kelas, jika diperlukan]

Pengumpulan

Kumpulkan satu link Google Colab saja. Nama dan NPM wajib berada pada sel Markdown paling atas. Sertakan kode, output yang tersimpan/terlihat serta analisis di notebook; tidak perlu mengumpulkan file .ipynb, ZIP, PDF atau screenshot terpisah.

  1. Jalankan sel dengan konfigurasi valid dan simpan notebook beserta output. Pastikan opsi menghilangkan output saat menyimpan tidak aktif untuk versi pengumpulan.
  2. Bagikan sebagai Viewer/Pelihat kepada dosen. Gunakan akses link jika diizinkan institusi; bila dibatasi, beri akses khusus akun dosen. Jangan memberi izin edit publik.
  3. Periksa akses dari akun penerima. Kirim URL notebook Colab, bukan folder Drive atau runtime sementara.
AspekBobotIndikator
Konversi dan channel20%BGR/RGB/grayscale/HSV serta peta channel ditampilkan dan ditafsirkan benar.
Deteksi tiga warna35%Mask HSV merah/hijau/biru berfungsi, termasuk dua interval merah.
Output dan parameter25%Sumber, mask, ekstraksi, jumlah pixel, dan batas warna dapat diperiksa.
Analisis dan pelaporan20%Kalibrasi serta kesalahan dijelaskan dari output; identitas dan link Viewer lengkap.