Mode belajar: tulis kode sendiri. Copy/cut, seleksi teks dan klik kanan dibatasi pada halaman; pembatasan UI bukan jaminan anti-penyalinan mutlak.
1. Tujuan
- Memilih kelas target dari model.names dan memvalidasi filter.
- Mengubah Results.boxes menjadi tabel koordinat dan confidence.
- Menghitung deteksi per kelas pada setiap gambar tanpa menebak jumlah objek.
- Membandingkan hitungan otomatis dengan hitungan manual dan menganalisis galat.
Prasyarat: Modul 10: instalasi Ultralytics, Results, bbox, confidence dan visualisasi BGR/RGB.
2. Materi Pembahasan

2.1 Counting dibangun di atas deteksi
Program penghitung objek bukan sekadar menampilkan gambar dengan kotak. Program perlu mendefinisikan kelas target, memilih kandidat yang memenuhi aturan, menghitungnya, lalu melaporkan hasil dengan konteks. Pada contoh kendaraan, target dapat berupa car, motorcycle, bus, dan truck jika nama tersebut tersedia pada model. Tidak semua alat transportasi atau bagian kendaraan menjadi kategori terpisah pada bobot pretrained.
Satu bbox yang lolos filter dihitung sebagai satu deteksi target pada satu gambar. Ini berbeda dari jumlah objek yang benar di dunia nyata. Objek yang sangat kecil, tertutup, kabur, atau berada di luar distribusi pelatihan dapat terlewat. Sebaliknya, pola latar dapat diprediksi sebagai kendaraan. Karena itu label laporan sebaiknya jumlah deteksi, bukan jumlah kendaraan pasti. Counting harus disertai pemeriksaan visual dan batasan.
2.2 Memilih kelas secara eksplisit
Pemetaan model.names menghubungkan ID numerik dengan nama kelas. Program membuat kamus kebalikannya agar mahasiswa memilih target dengan nama yang dapat dibaca. Langkah validasi menolak nama yang tidak tersedia dan daftar kosong. Untuk model custom, nama dan urutan mengikuti dataset training; jangan membawa asumsi ID dari model pretrained ke model tersebut.
Parameter classes pada predict menyaring keluaran ke ID target. Filter ini tidak melatih ulang model dan tidak menjadikan model lebih memahami kelas baru. Pilihan kelas harus sesuai tujuan program, misalnya person untuk menghitung orang atau kelompok kendaraan untuk menghitung lalu lintas dalam foto. Laporkan kelas yang dipilih agar pembaca mengetahui apakah sepeda, kereta, atau objek lain dikecualikan dari hitungan.
2.3 Dari tensor menjadi tabel yang transparan
Results.boxes menyediakan cls, conf, dan xyxy. Nilai tersebut dapat berada pada GPU, sehingga pemindahan ke CPU diperlukan sebelum diubah ke daftar Python untuk tabel. Setiap baris menyimpan identitas gambar, ID dan nama kelas, skor, serta koordinat bbox. Lebar dan tinggi dihitung dari perbedaan koordinat, bukan dari ukuran gambar keseluruhan.
Tabel rinci membantu memeriksa kesalahan yang sulit terlihat pada ringkasan. Contohnya, dua bbox dengan lokasi mirip mungkin merupakan kandidat berlebih, sementara bbox sangat kecil dapat berkaitan dengan objek jauh. Namun ukuran kotak tidak langsung berarti ukuran objek sebenarnya karena perspektif berbeda. Pertahankan kolom tabel walaupun tidak ada deteksi supaya analisis berikutnya tidak gagal karena skema kosong atau kolom yang hilang.
2.4 Confidence dan trade-off counting
Threshold confidence adalah keputusan operasional. Threshold tinggi dapat mengurangi kandidat keliru tetapi juga membuang objek benar yang sulit. Threshold rendah dapat memulihkan objek tersebut dengan risiko menambah false positive. Pengaruhnya tidak selalu monoton terhadap galat absolut counting karena kandidat benar dan salah dapat berubah bersamaan.
Bandingkan beberapa threshold pada gambar yang sama dan jangan mengubah filter kelas bersamaan jika ingin mengisolasi pengaruh confidence. Hitungan manual menjadi rujukan sederhana: catat objek target yang terlihat menurut kebijakan yang konsisten. Tentukan bagaimana memperlakukan objek terpotong, pantulan, gambar pada poster, dan objek sangat tertutup. Kebijakan anotasi yang tidak jelas akan menghasilkan perbandingan yang tidak adil meskipun programnya benar.
2.5 Evaluasi pada tingkat gambar dan objek
Galat hitungan dapat dinyatakan sebagai hitungan deteksi dikurangi hitungan manual. Nilai positif menunjukkan kelebihan hitungan dan nilai negatif menunjukkan kekurangan. Galat absolut menghilangkan tanda, tetapi angka nol tidak membuktikan semua deteksi benar: satu objek yang hilang dapat diimbangi oleh satu bbox palsu. Karena itu audit bbox dan hitungan harus dilakukan bersama.
Ringkasan antargambar berguna untuk membandingkan kondisi pencahayaan, kepadatan, dan ukuran objek. Menjumlahkan hitungan dari foto yang tumpang tindih tidak menghasilkan jumlah objek unik; kendaraan yang sama dapat muncul berulang. Praktikum ini membatasi kesimpulan pada tiap gambar. Sistem counting operasional juga memerlukan privasi, sumber gambar berizin, dan dokumentasi batasan agar angka tidak dipakai di luar kondisi pengujian yang telah dilakukan.
Video pembelajaran sesuai bab
Object Detection with Pre-trained Ultralytics YOLOv8 Model | Episode 1 — Ultralytics.
Fokus saat menonton: Ikuti inferensi pretrained YOLOv8 pada media, lalu hubungkan results.boxes dengan filter kelas dan hitungan per gambar.
Referensi dan sumber ilustrasi
3. Praktikum 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.
# Materi 11 — Pengolahan Citra
Nama: [Nama lengkap mahasiswa]
NPM: [NPM mahasiswa]
Kelas: [Kelas, jika diperlukan]- Jalankan notebook baru dengan identitas, instalasi, model, dan upload gambar.
- Tentukan kelas target berdasarkan daftar model.names yang tercetak.
- Jalankan counting dan periksa tabel bbox serta tabel hitungan per gambar.
- Masukkan hitungan manual setelah melihat citra asli; dokumentasikan kebijakan objek terpotong atau tertutup.
- Ulangi threshold pada input yang sama dan bandingkan hitungan serta bbox, bukan skor saja.
- Simpan notebook dengan semua output dan analisis; bagikan satu tautan Viewer.
Sel 1 — Instalasi Ultralytics
Jalankan sebagai sel tersendiri di Colab; tidak perlu meng-upgrade NumPy. Catat versi paket di sel berikutnya.
%pip install -q ultralyticsSel 2 — Model baseline dan direktori keluaran
Bobot yolov8n.pt diunduh saat pemuatan pertama. Ini baseline ringan, bukan pernyataan bahwa model ini yang terbaru. CPU dapat digunakan.
from pathlib import Path
import cv2, numpy as np, matplotlib.pyplot as plt
import torch, ultralytics
from ultralytics import YOLO
from google.colab import files
OUTPUT = Path('/content/hasil_yolo')
OUTPUT.mkdir(parents=True, exist_ok=True)
DEVICE = 0 if torch.cuda.is_available() else 'cpu'
model = YOLO('yolov8n.pt')
print('Ultralytics:', ultralytics.__version__, 'Device:', DEVICE)
print('Kelas model:', model.names)Sel 3 — Upload dan validasi gambar
Pilih satu atau lebih gambar berizin. Batas contoh: 20 gambar, maksimum 20 MB per gambar dan 20 megapiksel. Upload notebook memakai memori; jangan unggah berkas raksasa.
uploaded = files.upload()
if not uploaded or len(uploaded) > 20:
raise ValueError('Upload 1–20 gambar.')
images = []
for index, (name, content) in enumerate(uploaded.items()):
if Path(name).suffix.lower() not in {'.jpg', '.jpeg', '.png'}:
raise ValueError(f'Format tidak didukung: {name}')
if not (0 < len(content) <= 20 * 1024**2):
raise ValueError(f'Ukuran tidak valid: {name}')
image = cv2.imdecode(np.frombuffer(content, np.uint8), cv2.IMREAD_COLOR)
if image is None or image.shape[0] * image.shape[1] > 20_000_000:
raise ValueError(f'Gambar gagal dibaca atau terlalu besar: {name}')
images.append((f'{index:02}_{Path(name).stem}', image))
print('Gambar valid:', len(images))Sel 4 — Pilih objek berdasarkan nama kelas model
Contoh menghitung kendaraan dalam gambar. Ubah TARGET_NAMES menjadi nama yang benar-benar ada di model.names, bukan indeks kelas tebakan.
TARGET_NAMES = ['car', 'motorcycle', 'bus', 'truck']
CONF = 0.35
if not (0 < CONF <= 1):
raise ValueError('Confidence harus di rentang (0,1].')
name_to_id = {name: int(idx) for idx, name in model.names.items()}
unknown = set(TARGET_NAMES) - set(name_to_id)
if unknown or not TARGET_NAMES:
raise ValueError(f'Nama kelas tidak valid: {unknown}; lihat model.names.')
TARGET_IDS = [name_to_id[name] for name in TARGET_NAMES]
print('Filter:', dict(zip(TARGET_NAMES, TARGET_IDS)))Sel 5 — Deteksi, koordinat, dan counting per gambar
Filter class diterapkan saat predict; penghitung berasal dari bbox yang benar-benar dikembalikan. Deteksi nol tetap menghasilkan tabel dengan kolom yang konsisten.
import pandas as pd
from collections import Counter
from IPython.display import display
all_rows, count_rows = [], []
columns = ['gambar', 'class_id', 'class_name', 'confidence',
'x1', 'y1', 'x2', 'y2', 'width_px', 'height_px']
for name, image in images:
result = model.predict(image, conf=CONF, classes=TARGET_IDS,
device=DEVICE, imgsz=640, verbose=False)[0]
counts = Counter()
for box in result.boxes:
class_id = int(box.cls.item())
class_name = model.names[class_id]
x1, y1, x2, y2 = box.xyxy[0].cpu().tolist()
score = float(box.conf.item())
counts[class_name] += 1
all_rows.append(dict(gambar=name, class_id=class_id,
class_name=class_name, confidence=score, x1=x1, y1=y1,
x2=x2, y2=y2, width_px=x2-x1, height_px=y2-y1))
count_rows.append({'gambar': name, **{n: counts[n] for n in TARGET_NAMES},
'total_deteksi_target': sum(counts.values())})
annotated = result.plot()
if not cv2.imwrite(str(OUTPUT / f'{name}_count.jpg'), annotated):
raise IOError('Gagal menyimpan citra hasil.')
plt.figure(figsize=(10, 7))
plt.imshow(cv2.cvtColor(annotated, cv2.COLOR_BGR2RGB))
plt.title(f'{name} — {dict(counts)}'); plt.axis('off'); plt.show()
detections = pd.DataFrame(all_rows, columns=columns)
count_table = pd.DataFrame(count_rows)
display(detections); display(count_table)
detections.to_csv(OUTPUT / 'bbox.csv', index=False)
count_table.to_csv(OUTPUT / 'counting.csv', index=False)Sel 6 — Masukkan hitungan manual dan hitung galat
Isi saat prompt berdasarkan gambar asli dan kebijakan target yang sama. Nilai manual tidak disiapkan sebagai ground truth buatan.
manual_rows = []
for name, image in images:
plt.figure(figsize=(9, 6))
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.title(f'Hitung manual: {name}'); plt.axis('off'); plt.show()
raw = input(f'Jumlah manual objek target untuk {name}: ').strip()
if not raw.isdigit():
raise ValueError('Masukkan bilangan bulat nonnegatif.')
manual_rows.append({'gambar': name, 'jumlah_manual': int(raw)})
audit = count_table.merge(pd.DataFrame(manual_rows), on='gambar', validate='one_to_one')
audit['galat'] = audit['total_deteksi_target'] - audit['jumlah_manual']
audit['galat_absolut'] = audit['galat'].abs()
display(audit)
print('Rata-rata galat absolut hitungan:', audit['galat_absolut'].mean())
audit.to_csv(OUTPUT / 'audit_counting.csv', index=False)Jika terjadi error
- Filter nama tidak dikenali.
- Periksa model.names; gunakan nama persis dari model atau latih custom, bukan membuat ID baru.
- Tabel counting menyatakan nol.
- Nol adalah hasil sah. Cek objek terlihat, kelas target dan threshold tanpa menambah bbox manual sebagai hasil model.
- Galat hitungan nol dianggap sempurna.
- Periksa bbox satu per satu karena false positive dan false negative dapat saling meniadakan.
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 11
Buat program menghitung kendaraan atau objek tertentu pada gambar, dengan class filter dan tabel hasil yang dapat diaudit.
Ketentuan pengerjaan
- Pilih kategori target yang tersedia dan jelaskan alasan pemilihannya.
- Gunakan sedikitnya 5 gambar berizin dengan variasi kepadatan atau kondisi.
- Tampilkan anotasi, tabel confidence/xyxy dan hitungan per kelas setiap gambar.
- Bandingkan dengan hitungan manual dan minimal dua threshold; jelaskan kesalahan bbox, bukan hanya total.
- Simpan counting.csv, bbox.csv dan audit dalam runtime serta tampilkan ringkasannya di notebook.
- Kumpulkan hanya SATU link Google Colab, output dan analisis terlihat, akses Viewer, Markdown Nama dan NPM di atas.
Pertanyaan analisis
- Apakah galat total nol menjamin semua bbox benar?
- Kondisi mana paling sering menyebabkan false negative?
- Bagaimana definisi kelas dan kebijakan hitungan manual memengaruhi evaluasi?
# Materi 11 — 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.
- Jalankan sel dengan konfigurasi valid dan simpan notebook beserta output. Pastikan opsi menghilangkan output saat menyimpan tidak aktif untuk versi pengumpulan.
- Bagikan sebagai Viewer/Pelihat kepada dosen. Gunakan akses link jika diizinkan institusi; bila dibatasi, beri akses khusus akun dosen. Jangan memberi izin edit publik.
- Periksa akses dari akun penerima. Kirim URL notebook Colab, bukan folder Drive atau runtime sementara.
| Aspek | Bobot | Indikator |
|---|---|---|
| Filter dan implementasi counting | 35% | Pemetaan kelas benar dan jumlah dihitung dari keluaran nyata. |
| Tabel dan visualisasi | 25% | BBox, confidence, koordinat dan hitungan jelas. |
| Evaluasi manual dan threshold | 30% | Audit konsisten, minimal dua threshold dan analisis kesalahan. |
| Reproduksibilitas | 10% | Input, parameter dan notebook Viewer lengkap. |