add requirements.txt
This commit is contained in:
parent
fd09fc6bc2
commit
e3c0cf0b1b
|
@ -0,0 +1,287 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "37fe6724-f5fe-412a-ab9a-6a1df878c308",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Import Library"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 15,
|
||||||
|
"id": "11b66fe3-8d38-4bf9-b9c5-f8bd3213bd55",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"Selesai Import Library\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"import cv2 # Import library OpenCV untuk pengolahan citra dan video\n",
|
||||||
|
"import imutils # Import library imutils untuk mempermudah manipulasi citra\n",
|
||||||
|
"import numpy as np # Import library numpy untuk operasi numerik\n",
|
||||||
|
"from ultralytics import YOLO # Import class YOLO dari library ultralytics untuk deteksi objek\n",
|
||||||
|
"from collections import defaultdict # Import class defaultdict dari library collections untuk struktur data default dictionary\n",
|
||||||
|
"\n",
|
||||||
|
"print(\"Selesai Import Library\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "243e5a8f-46c2-4fe1-b174-52a46f0a26ee",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Deklarasi Variable"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 16,
|
||||||
|
"id": "bbeb303b-5683-44cc-a924-0f2481d75528",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"selesai deklarasi variable\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"color = (0, 255, 0) # Warna hijau untuk penggambaran objek dan garis\n",
|
||||||
|
"color_red = (0, 0, 255) # Warna merah untuk teks dan garis\n",
|
||||||
|
"thickness = 2 # Ketebalan garis untuk penggambaran objek dan garis\n",
|
||||||
|
"\n",
|
||||||
|
"font = cv2.FONT_HERSHEY_SIMPLEX # Jenis font untuk teks\n",
|
||||||
|
"font_scale = 0.5 # Skala font untuk teks\n",
|
||||||
|
"\n",
|
||||||
|
"# Path video yang akan diproses\n",
|
||||||
|
"video_path = \"video.mp4\"\n",
|
||||||
|
"model_path = \"models/yolov8n.pt\"\n",
|
||||||
|
"\n",
|
||||||
|
"# Buka video\n",
|
||||||
|
"cap = cv2.VideoCapture(video_path)\n",
|
||||||
|
"# Inisialisasi model YOLO dengan file weight yang telah dilatih sebelumnya\n",
|
||||||
|
"model = YOLO(model_path)\n",
|
||||||
|
"\n",
|
||||||
|
"# Ukuran frame video\n",
|
||||||
|
"width = 1280\n",
|
||||||
|
"height = 720\n",
|
||||||
|
"\n",
|
||||||
|
"# Inisialisasi objek untuk menyimpan video hasil pemrosesan\n",
|
||||||
|
"fourcc = cv2.VideoWriter_fourcc(*'XVID')\n",
|
||||||
|
"writer = cv2.VideoWriter(\"video.avi\", fourcc, 20.0, (width, height))\n",
|
||||||
|
"\n",
|
||||||
|
"# Id objek kendaraan yang ingin dilacak berdasarkan kelas di file coco-classes.txt\n",
|
||||||
|
"vehicle_ids = [2, 3, 5, 7]\n",
|
||||||
|
"# Dictionary untuk menyimpan sejarah pergerakan setiap kendaraan yang terdeteksi\n",
|
||||||
|
"track_history = defaultdict(lambda: [])\n",
|
||||||
|
"\n",
|
||||||
|
"up = {} # Dictionary untuk kendaraan yang melewati garis atas\n",
|
||||||
|
"down = {} # Dictionary untuk kendaraan yang melewati garis bawah\n",
|
||||||
|
"threshold = 400 # Ambang batas garis pemisah kendaraan\n",
|
||||||
|
"\n",
|
||||||
|
"print(\"selesai deklarasi variable\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "00596875-56e1-445a-bd8b-b2b3a73a411a",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Fungsi untuk mengambil titik tengah dari bounding box objek "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 17,
|
||||||
|
"id": "ffcffbd1-ad9b-4908-8930-bea2ba6b6ecb",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"Selesai membuat fungsi\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"def pega_centro(x, y, w, h):\n",
|
||||||
|
" x1 = int(w / 2)\n",
|
||||||
|
" y1 = int(h / 2)\n",
|
||||||
|
" cx = x + x1\n",
|
||||||
|
" cy = y + y1\n",
|
||||||
|
" return cx, cy\n",
|
||||||
|
"\n",
|
||||||
|
"print(\"Selesai membuat fungsi\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "9f2e6c12-a70b-49f2-9083-a9c85b04e842",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Background subtraction menggunakan MOG2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 18,
|
||||||
|
"id": "4b0f68b8-9216-49e6-892e-bbf2282d73b3",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"selesai\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"subtracao = cv2.createBackgroundSubtractorMOG2()\n",
|
||||||
|
"print(\"selesai\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "0e9ea925-a617-45d3-b50c-273f4ee0163b",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Proses Video "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 19,
|
||||||
|
"id": "705c59f4-fba5-498d-9e51-d002a0dc3226",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Loop utama untuk membaca setiap frame dari video\n",
|
||||||
|
"while True:\n",
|
||||||
|
" ret, frame = cap.read() # Membaca frame dari video\n",
|
||||||
|
" if ret == False: # Keluar dari loop jika tidak ada frame yang dapat dibaca\n",
|
||||||
|
" break\n",
|
||||||
|
" \n",
|
||||||
|
" try:\n",
|
||||||
|
" frame_color = frame.copy() # Salin frame ke mode warna untuk pengolahan dan penggambaran\n",
|
||||||
|
" frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Konversi frame ke citra grayscale\n",
|
||||||
|
" frame_gray = cv2.cvtColor(frame_gray, cv2.COLOR_GRAY2BGR) # Konversi kembali ke citra BGR untuk tampilan grayscale\n",
|
||||||
|
" frame_bw = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Konversi ke citra grayscale untuk mode black and white\n",
|
||||||
|
"\n",
|
||||||
|
" # Deteksi objek menggunakan model YOLO\n",
|
||||||
|
" results = model.track(frame_color, persist=True, verbose=False)[0]\n",
|
||||||
|
" bboxes = np.array(results.boxes.data.tolist(), dtype=\"int\") # Koordinat bounding box objek yang terdeteksi\n",
|
||||||
|
"\n",
|
||||||
|
" # Gambar garis pembatas untuk menghitung jumlah kendaraan yang melewati garis\n",
|
||||||
|
" cv2.line(frame_color, (0, threshold), (1280, threshold), color, thickness)\n",
|
||||||
|
" cv2.putText(frame_color, \"Pembatas Jalan\", (620, 445), font, 0.7, color_red, thickness)\n",
|
||||||
|
"\n",
|
||||||
|
" # Loop untuk setiap objek yang terdeteksi\n",
|
||||||
|
" for box in bboxes:\n",
|
||||||
|
" x1, y1, x2, y2, track_id, score, class_id = box # Ambil koordinat dan informasi lainnya\n",
|
||||||
|
" cx = int((x1 + x2) / 2) # Hitung koordinat x pusat objek\n",
|
||||||
|
" cy = int((y1 + y2) / 2) # Hitung koordinat y pusat objek\n",
|
||||||
|
" if class_id in vehicle_ids: # Periksa apakah objek merupakan kendaraan yang ingin dilacak\n",
|
||||||
|
" class_name = results.names[int(class_id)].upper() # Dapatkan nama kelas objek\n",
|
||||||
|
"\n",
|
||||||
|
" track = track_history[track_id] # Ambil sejarah pergerakan objek berdasarkan ID\n",
|
||||||
|
" track.append((cx, cy)) # Tambahkan koordinat pusat objek ke dalam sejarah pergerakan\n",
|
||||||
|
" if len(track) > 20: # Batasi panjang sejarah pergerakan agar tidak terlalu panjang\n",
|
||||||
|
" track.pop(0) # Hapus elemen pertama jika sejarah sudah melebihi batas\n",
|
||||||
|
"\n",
|
||||||
|
" points = np.hstack(track).astype(\"int32\").reshape(-1, 1, 2) # Konversi sejarah pergerakan ke format yang sesuai untuk penggambaran\n",
|
||||||
|
" cv2.polylines(frame_color, [points], isClosed=False, color=color, thickness=thickness) # Gambar garis yang merepresentasikan sejarah pergerakan\n",
|
||||||
|
" cv2.rectangle(frame_color, (x1, y1), (x2, y2), color, thickness) # Gambar bounding box objek\n",
|
||||||
|
" text = \"ID: {} {}\".format(track_id, class_name) # Buat teks ID objek dan nama kelasnya\n",
|
||||||
|
" cv2.putText(frame_color, text, (x1, y1 - 5), font, font_scale, color, thickness) # Tampilkan teks di atas objek\n",
|
||||||
|
"\n",
|
||||||
|
" if cy > threshold - 5 and cy < threshold + 5 and cx < 670: # Periksa apakah objek melewati garis atas\n",
|
||||||
|
" down[track_id] = x1, y1, x2, y2 # Simpan informasi objek yang melewati garis atas\n",
|
||||||
|
"\n",
|
||||||
|
" if cy > threshold - 5 and cy < threshold + 5 and cx > 670: # Periksa apakah objek melewati garis bawah\n",
|
||||||
|
" up[track_id] = x1, y1, x2, y2 # Simpan informasi objek yang melewati garis bawah\n",
|
||||||
|
"\n",
|
||||||
|
" up_text = \"Kanan:{}\".format(len(list(up.keys()))) # Buat teks jumlah kendaraan yang melewati garis atas\n",
|
||||||
|
" down_text = \"Kiri:{}\".format(len(list(down.keys()))) # Buat teks jumlah kendaraan yang melewati garis bawah\n",
|
||||||
|
"\n",
|
||||||
|
" cv2.putText(frame_color, up_text, (1150, threshold - 5), font, 0.8, color_red, thickness) # Tampilkan teks jumlah kendaraan yang melewati garis atas\n",
|
||||||
|
" cv2.putText(frame_color, down_text, (0, threshold - 5), font, 0.8, color_red, thickness) # Tampilkan teks jumlah kendaraan yang melewati garis bawah\n",
|
||||||
|
"\n",
|
||||||
|
" # Background subtraction dan deteksi kontur\n",
|
||||||
|
" grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Konversi frame ke citra grayscale\n",
|
||||||
|
" blur = cv2.GaussianBlur(grey, (3, 3), 5) # Reduksi noise menggunakan Gaussian Blur\n",
|
||||||
|
" img_sub = subtracao.apply(blur) # Background subtraction\n",
|
||||||
|
" dilat = cv2.dilate(img_sub, np.ones((5, 5))) # Dilasi untuk meningkatkan ketebalan objek\n",
|
||||||
|
" kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) # Kernel untuk operasi morfologi\n",
|
||||||
|
" dilatada = cv2.morphologyEx(dilat, cv2.MORPH_CLOSE, kernel) # Operasi closing untuk mengisi lubang kecil pada objek\n",
|
||||||
|
" dilatada = cv2.morphologyEx(dilatada, cv2.MORPH_CLOSE, kernel) # Operasi closing tambahan\n",
|
||||||
|
" contorno, h = cv2.findContours(dilatada, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # Deteksi kontur objek\n",
|
||||||
|
"\n",
|
||||||
|
" writer.write(frame_color) # Menyimpan frame hasil pemrosesan\n",
|
||||||
|
" # Menampilkan gambar\n",
|
||||||
|
" cv2.imshow(\"Warna\", frame_color) # Tampilkan mode warna\n",
|
||||||
|
" cv2.imshow(\"Grayscale\", frame_gray) # Tampilkan mode grayscale\n",
|
||||||
|
" cv2.imshow(\"Detectar\", dilatada) # Tampilkan mode Detectar dilatada\n",
|
||||||
|
" if cv2.waitKey(10) & 0xFF == ord(\"q\"): # Keluar saat tombol q ditekan\n",
|
||||||
|
" break\n",
|
||||||
|
"\n",
|
||||||
|
" except Exception as e:\n",
|
||||||
|
" print(\"Terjadi kesalahan:\", str(e)) # Tangkap dan tampilkan kesalahan yang terjadi\n",
|
||||||
|
" continue # Lanjutkan ke iterasi berikutnya\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "08ead243-3140-4f0f-a54b-9c93db2ae6df",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
" \n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 20,
|
||||||
|
"id": "15c70b25-1b92-43d8-9167-ebb88b2a8df7",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"cap.release() # Bebaskan sumber daya setelah selesai pemrosesan video\n",
|
||||||
|
"writer.release() # Tutup objek writer\n",
|
||||||
|
"cv2.destroyAllWindows() # Tutup semua jendela yang dibuka oleh OpenCV"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3 (ipykernel)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.10.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
|
@ -0,0 +1,287 @@
|
||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "37fe6724-f5fe-412a-ab9a-6a1df878c308",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Import Library"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 15,
|
||||||
|
"id": "11b66fe3-8d38-4bf9-b9c5-f8bd3213bd55",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"Selesai Import Library\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"import cv2 # Import library OpenCV untuk pengolahan citra dan video\n",
|
||||||
|
"import imutils # Import library imutils untuk mempermudah manipulasi citra\n",
|
||||||
|
"import numpy as np # Import library numpy untuk operasi numerik\n",
|
||||||
|
"from ultralytics import YOLO # Import class YOLO dari library ultralytics untuk deteksi objek\n",
|
||||||
|
"from collections import defaultdict # Import class defaultdict dari library collections untuk struktur data default dictionary\n",
|
||||||
|
"\n",
|
||||||
|
"print(\"Selesai Import Library\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "243e5a8f-46c2-4fe1-b174-52a46f0a26ee",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Deklarasi Variable"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 16,
|
||||||
|
"id": "bbeb303b-5683-44cc-a924-0f2481d75528",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"selesai deklarasi variable\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"color = (0, 255, 0) # Warna hijau untuk penggambaran objek dan garis\n",
|
||||||
|
"color_red = (0, 0, 255) # Warna merah untuk teks dan garis\n",
|
||||||
|
"thickness = 2 # Ketebalan garis untuk penggambaran objek dan garis\n",
|
||||||
|
"\n",
|
||||||
|
"font = cv2.FONT_HERSHEY_SIMPLEX # Jenis font untuk teks\n",
|
||||||
|
"font_scale = 0.5 # Skala font untuk teks\n",
|
||||||
|
"\n",
|
||||||
|
"# Path video yang akan diproses\n",
|
||||||
|
"video_path = \"video.mp4\"\n",
|
||||||
|
"model_path = \"models/yolov8n.pt\"\n",
|
||||||
|
"\n",
|
||||||
|
"# Buka video\n",
|
||||||
|
"cap = cv2.VideoCapture(video_path)\n",
|
||||||
|
"# Inisialisasi model YOLO dengan file weight yang telah dilatih sebelumnya\n",
|
||||||
|
"model = YOLO(model_path)\n",
|
||||||
|
"\n",
|
||||||
|
"# Ukuran frame video\n",
|
||||||
|
"width = 1280\n",
|
||||||
|
"height = 720\n",
|
||||||
|
"\n",
|
||||||
|
"# Inisialisasi objek untuk menyimpan video hasil pemrosesan\n",
|
||||||
|
"fourcc = cv2.VideoWriter_fourcc(*'XVID')\n",
|
||||||
|
"writer = cv2.VideoWriter(\"video.avi\", fourcc, 20.0, (width, height))\n",
|
||||||
|
"\n",
|
||||||
|
"# Id objek kendaraan yang ingin dilacak berdasarkan kelas di file coco-classes.txt\n",
|
||||||
|
"vehicle_ids = [2, 3, 5, 7]\n",
|
||||||
|
"# Dictionary untuk menyimpan sejarah pergerakan setiap kendaraan yang terdeteksi\n",
|
||||||
|
"track_history = defaultdict(lambda: [])\n",
|
||||||
|
"\n",
|
||||||
|
"up = {} # Dictionary untuk kendaraan yang melewati garis atas\n",
|
||||||
|
"down = {} # Dictionary untuk kendaraan yang melewati garis bawah\n",
|
||||||
|
"threshold = 400 # Ambang batas garis pemisah kendaraan\n",
|
||||||
|
"\n",
|
||||||
|
"print(\"selesai deklarasi variable\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "00596875-56e1-445a-bd8b-b2b3a73a411a",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Fungsi untuk mengambil titik tengah dari bounding box objek "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 17,
|
||||||
|
"id": "ffcffbd1-ad9b-4908-8930-bea2ba6b6ecb",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"Selesai membuat fungsi\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"def pega_centro(x, y, w, h):\n",
|
||||||
|
" x1 = int(w / 2)\n",
|
||||||
|
" y1 = int(h / 2)\n",
|
||||||
|
" cx = x + x1\n",
|
||||||
|
" cy = y + y1\n",
|
||||||
|
" return cx, cy\n",
|
||||||
|
"\n",
|
||||||
|
"print(\"Selesai membuat fungsi\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "9f2e6c12-a70b-49f2-9083-a9c85b04e842",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Background subtraction menggunakan MOG2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 18,
|
||||||
|
"id": "4b0f68b8-9216-49e6-892e-bbf2282d73b3",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"selesai\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"subtracao = cv2.createBackgroundSubtractorMOG2()\n",
|
||||||
|
"print(\"selesai\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"id": "0e9ea925-a617-45d3-b50c-273f4ee0163b",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Proses Video "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 19,
|
||||||
|
"id": "705c59f4-fba5-498d-9e51-d002a0dc3226",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Loop utama untuk membaca setiap frame dari video\n",
|
||||||
|
"while True:\n",
|
||||||
|
" ret, frame = cap.read() # Membaca frame dari video\n",
|
||||||
|
" if ret == False: # Keluar dari loop jika tidak ada frame yang dapat dibaca\n",
|
||||||
|
" break\n",
|
||||||
|
" \n",
|
||||||
|
" try:\n",
|
||||||
|
" frame_color = frame.copy() # Salin frame ke mode warna untuk pengolahan dan penggambaran\n",
|
||||||
|
" frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Konversi frame ke citra grayscale\n",
|
||||||
|
" frame_gray = cv2.cvtColor(frame_gray, cv2.COLOR_GRAY2BGR) # Konversi kembali ke citra BGR untuk tampilan grayscale\n",
|
||||||
|
" frame_bw = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Konversi ke citra grayscale untuk mode black and white\n",
|
||||||
|
"\n",
|
||||||
|
" # Deteksi objek menggunakan model YOLO\n",
|
||||||
|
" results = model.track(frame_color, persist=True, verbose=False)[0]\n",
|
||||||
|
" bboxes = np.array(results.boxes.data.tolist(), dtype=\"int\") # Koordinat bounding box objek yang terdeteksi\n",
|
||||||
|
"\n",
|
||||||
|
" # Gambar garis pembatas untuk menghitung jumlah kendaraan yang melewati garis\n",
|
||||||
|
" cv2.line(frame_color, (0, threshold), (1280, threshold), color, thickness)\n",
|
||||||
|
" cv2.putText(frame_color, \"Pembatas Jalan\", (620, 445), font, 0.7, color_red, thickness)\n",
|
||||||
|
"\n",
|
||||||
|
" # Loop untuk setiap objek yang terdeteksi\n",
|
||||||
|
" for box in bboxes:\n",
|
||||||
|
" x1, y1, x2, y2, track_id, score, class_id = box # Ambil koordinat dan informasi lainnya\n",
|
||||||
|
" cx = int((x1 + x2) / 2) # Hitung koordinat x pusat objek\n",
|
||||||
|
" cy = int((y1 + y2) / 2) # Hitung koordinat y pusat objek\n",
|
||||||
|
" if class_id in vehicle_ids: # Periksa apakah objek merupakan kendaraan yang ingin dilacak\n",
|
||||||
|
" class_name = results.names[int(class_id)].upper() # Dapatkan nama kelas objek\n",
|
||||||
|
"\n",
|
||||||
|
" track = track_history[track_id] # Ambil sejarah pergerakan objek berdasarkan ID\n",
|
||||||
|
" track.append((cx, cy)) # Tambahkan koordinat pusat objek ke dalam sejarah pergerakan\n",
|
||||||
|
" if len(track) > 20: # Batasi panjang sejarah pergerakan agar tidak terlalu panjang\n",
|
||||||
|
" track.pop(0) # Hapus elemen pertama jika sejarah sudah melebihi batas\n",
|
||||||
|
"\n",
|
||||||
|
" points = np.hstack(track).astype(\"int32\").reshape(-1, 1, 2) # Konversi sejarah pergerakan ke format yang sesuai untuk penggambaran\n",
|
||||||
|
" cv2.polylines(frame_color, [points], isClosed=False, color=color, thickness=thickness) # Gambar garis yang merepresentasikan sejarah pergerakan\n",
|
||||||
|
" cv2.rectangle(frame_color, (x1, y1), (x2, y2), color, thickness) # Gambar bounding box objek\n",
|
||||||
|
" text = \"ID: {} {}\".format(track_id, class_name) # Buat teks ID objek dan nama kelasnya\n",
|
||||||
|
" cv2.putText(frame_color, text, (x1, y1 - 5), font, font_scale, color, thickness) # Tampilkan teks di atas objek\n",
|
||||||
|
"\n",
|
||||||
|
" if cy > threshold - 5 and cy < threshold + 5 and cx < 670: # Periksa apakah objek melewati garis atas\n",
|
||||||
|
" down[track_id] = x1, y1, x2, y2 # Simpan informasi objek yang melewati garis atas\n",
|
||||||
|
"\n",
|
||||||
|
" if cy > threshold - 5 and cy < threshold + 5 and cx > 670: # Periksa apakah objek melewati garis bawah\n",
|
||||||
|
" up[track_id] = x1, y1, x2, y2 # Simpan informasi objek yang melewati garis bawah\n",
|
||||||
|
"\n",
|
||||||
|
" up_text = \"Kanan:{}\".format(len(list(up.keys()))) # Buat teks jumlah kendaraan yang melewati garis atas\n",
|
||||||
|
" down_text = \"Kiri:{}\".format(len(list(down.keys()))) # Buat teks jumlah kendaraan yang melewati garis bawah\n",
|
||||||
|
"\n",
|
||||||
|
" cv2.putText(frame_color, up_text, (1150, threshold - 5), font, 0.8, color_red, thickness) # Tampilkan teks jumlah kendaraan yang melewati garis atas\n",
|
||||||
|
" cv2.putText(frame_color, down_text, (0, threshold - 5), font, 0.8, color_red, thickness) # Tampilkan teks jumlah kendaraan yang melewati garis bawah\n",
|
||||||
|
"\n",
|
||||||
|
" # Background subtraction dan deteksi kontur\n",
|
||||||
|
" grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # Konversi frame ke citra grayscale\n",
|
||||||
|
" blur = cv2.GaussianBlur(grey, (3, 3), 5) # Reduksi noise menggunakan Gaussian Blur\n",
|
||||||
|
" img_sub = subtracao.apply(blur) # Background subtraction\n",
|
||||||
|
" dilat = cv2.dilate(img_sub, np.ones((5, 5))) # Dilasi untuk meningkatkan ketebalan objek\n",
|
||||||
|
" kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) # Kernel untuk operasi morfologi\n",
|
||||||
|
" dilatada = cv2.morphologyEx(dilat, cv2.MORPH_CLOSE, kernel) # Operasi closing untuk mengisi lubang kecil pada objek\n",
|
||||||
|
" dilatada = cv2.morphologyEx(dilatada, cv2.MORPH_CLOSE, kernel) # Operasi closing tambahan\n",
|
||||||
|
" contorno, h = cv2.findContours(dilatada, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # Deteksi kontur objek\n",
|
||||||
|
"\n",
|
||||||
|
" writer.write(frame_color) # Menyimpan frame hasil pemrosesan\n",
|
||||||
|
" # Menampilkan gambar\n",
|
||||||
|
" cv2.imshow(\"Warna\", frame_color) # Tampilkan mode warna\n",
|
||||||
|
" cv2.imshow(\"Grayscale\", frame_gray) # Tampilkan mode grayscale\n",
|
||||||
|
" cv2.imshow(\"Detectar\", dilatada) # Tampilkan mode Detectar dilatada\n",
|
||||||
|
" if cv2.waitKey(10) & 0xFF == ord(\"q\"): # Keluar saat tombol q ditekan\n",
|
||||||
|
" break\n",
|
||||||
|
"\n",
|
||||||
|
" except Exception as e:\n",
|
||||||
|
" print(\"Terjadi kesalahan:\", str(e)) # Tangkap dan tampilkan kesalahan yang terjadi\n",
|
||||||
|
" continue # Lanjutkan ke iterasi berikutnya\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"id": "08ead243-3140-4f0f-a54b-9c93db2ae6df",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
" \n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 20,
|
||||||
|
"id": "15c70b25-1b92-43d8-9167-ebb88b2a8df7",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"cap.release() # Bebaskan sumber daya setelah selesai pemrosesan video\n",
|
||||||
|
"writer.release() # Tutup objek writer\n",
|
||||||
|
"cv2.destroyAllWindows() # Tutup semua jendela yang dibuka oleh OpenCV"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3 (ipykernel)",
|
||||||
|
"language": "python",
|
||||||
|
"name": "python3"
|
||||||
|
},
|
||||||
|
"language_info": {
|
||||||
|
"codemirror_mode": {
|
||||||
|
"name": "ipython",
|
||||||
|
"version": 3
|
||||||
|
},
|
||||||
|
"file_extension": ".py",
|
||||||
|
"mimetype": "text/x-python",
|
||||||
|
"name": "python",
|
||||||
|
"nbconvert_exporter": "python",
|
||||||
|
"pygments_lexer": "ipython3",
|
||||||
|
"version": "3.10.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
anyio==4.3.0
|
||||||
|
appnope==0.1.4
|
||||||
|
argon2-cffi==23.1.0
|
||||||
|
argon2-cffi-bindings==21.2.0
|
||||||
|
arrow==1.3.0
|
||||||
|
asttokens==2.4.1
|
||||||
|
async-lru==2.0.4
|
||||||
|
attrs==23.2.0
|
||||||
|
Babel==2.14.0
|
||||||
|
beautifulsoup4==4.12.3
|
||||||
|
bleach==6.1.0
|
||||||
|
certifi==2024.2.2
|
||||||
|
cffi==1.16.0
|
||||||
|
charset-normalizer==3.3.2
|
||||||
|
comm==0.2.1
|
||||||
|
contourpy==1.2.0
|
||||||
|
cycler==0.12.1
|
||||||
|
Cython==3.0.8
|
||||||
|
debugpy==1.8.1
|
||||||
|
decorator==5.1.1
|
||||||
|
defusedxml==0.7.1
|
||||||
|
exceptiongroup==1.2.0
|
||||||
|
executing==2.0.1
|
||||||
|
fastjsonschema==2.19.1
|
||||||
|
filelock==3.13.1
|
||||||
|
fonttools==4.49.0
|
||||||
|
fqdn==1.5.1
|
||||||
|
fsspec==2024.2.0
|
||||||
|
h11==0.14.0
|
||||||
|
httpcore==1.0.3
|
||||||
|
httpx==0.26.0
|
||||||
|
idna==3.6
|
||||||
|
imutils==0.5.4
|
||||||
|
ipykernel==6.29.2
|
||||||
|
ipython==8.21.0
|
||||||
|
isoduration==20.11.0
|
||||||
|
jedi==0.19.1
|
||||||
|
Jinja2==3.1.3
|
||||||
|
json5==0.9.17
|
||||||
|
jsonpointer==2.4
|
||||||
|
jsonschema==4.21.1
|
||||||
|
jsonschema-specifications==2023.12.1
|
||||||
|
jupyter-events==0.9.0
|
||||||
|
jupyter-lsp==2.2.2
|
||||||
|
jupyter_client==8.6.0
|
||||||
|
jupyter_core==5.7.1
|
||||||
|
jupyter_server==2.12.5
|
||||||
|
jupyter_server_terminals==0.5.2
|
||||||
|
jupyterlab==4.1.2
|
||||||
|
jupyterlab_pygments==0.3.0
|
||||||
|
jupyterlab_server==2.25.3
|
||||||
|
kiwisolver==1.4.5
|
||||||
|
lapx==0.5.5
|
||||||
|
MarkupSafe==2.1.5
|
||||||
|
matplotlib==3.8.3
|
||||||
|
matplotlib-inline==0.1.6
|
||||||
|
mistune==3.0.2
|
||||||
|
mpmath==1.3.0
|
||||||
|
nbclient==0.9.0
|
||||||
|
nbconvert==7.16.1
|
||||||
|
nbformat==5.9.2
|
||||||
|
nest-asyncio==1.6.0
|
||||||
|
networkx==3.2.1
|
||||||
|
notebook==7.1.0
|
||||||
|
notebook_shim==0.2.4
|
||||||
|
numpy==1.26.4
|
||||||
|
opencv-python==4.9.0.80
|
||||||
|
overrides==7.7.0
|
||||||
|
packaging==23.2
|
||||||
|
pandas==2.2.0
|
||||||
|
pandocfilters==1.5.1
|
||||||
|
parso==0.8.3
|
||||||
|
pexpect==4.9.0
|
||||||
|
pillow==10.2.0
|
||||||
|
platformdirs==4.2.0
|
||||||
|
prometheus_client==0.20.0
|
||||||
|
prompt-toolkit==3.0.43
|
||||||
|
psutil==5.9.8
|
||||||
|
ptyprocess==0.7.0
|
||||||
|
pure-eval==0.2.2
|
||||||
|
py-cpuinfo==9.0.0
|
||||||
|
pycparser==2.21
|
||||||
|
Pygments==2.17.2
|
||||||
|
pyparsing==3.1.1
|
||||||
|
python-dateutil==2.8.2
|
||||||
|
python-json-logger==2.0.7
|
||||||
|
pytz==2024.1
|
||||||
|
PyYAML==6.0.1
|
||||||
|
pyzmq==25.1.2
|
||||||
|
referencing==0.33.0
|
||||||
|
requests==2.31.0
|
||||||
|
rfc3339-validator==0.1.4
|
||||||
|
rfc3986-validator==0.1.1
|
||||||
|
rpds-py==0.18.0
|
||||||
|
scipy==1.12.0
|
||||||
|
seaborn==0.13.2
|
||||||
|
Send2Trash==1.8.2
|
||||||
|
six==1.16.0
|
||||||
|
sniffio==1.3.0
|
||||||
|
soupsieve==2.5
|
||||||
|
stack-data==0.6.3
|
||||||
|
sympy==1.12
|
||||||
|
terminado==0.18.0
|
||||||
|
thop==0.1.1.post2209072238
|
||||||
|
tinycss2==1.2.1
|
||||||
|
tomli==2.0.1
|
||||||
|
torch==2.2.0
|
||||||
|
torchvision==0.17.0
|
||||||
|
tornado==6.4
|
||||||
|
tqdm==4.66.2
|
||||||
|
traitlets==5.14.1
|
||||||
|
types-python-dateutil==2.8.19.20240106
|
||||||
|
typing_extensions==4.9.0
|
||||||
|
tzdata==2024.1
|
||||||
|
ultralytics==8.1.16
|
||||||
|
uri-template==1.3.0
|
||||||
|
urllib3==2.2.1
|
||||||
|
wcwidth==0.2.13
|
||||||
|
webcolors==1.13
|
||||||
|
webencodings==0.5.1
|
||||||
|
websocket-client==1.7.0
|
Loading…
Reference in New Issue