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