refactor: single predict.py entrypoint (production + CLI), archive experiments
ci / smoke (push) Canceled after 0s
ci / smoke (push) Canceled after 0s
This commit is contained in:
1 parent
beb9c9fb6b
commit
52d3127302
36 files changed
+161
-48
No files matched your search
@@ -0,0 +1,207 @@
|
||||
import cv2
|
||||
import os
|
||||
import json
|
||||
import numpy as np
|
||||
|
||||
# State constants
|
||||
STATE_TRUCK = 0
|
||||
STATE_DETECTION = 1
|
||||
STATE_LINE = 2
|
||||
STATE_DONE = 3
|
||||
|
||||
state = STATE_TRUCK
|
||||
points_truck = []
|
||||
points_detection = []
|
||||
points_line = []
|
||||
|
||||
def click_event(event, x, y, flags, params):
|
||||
global state
|
||||
if event == cv2.EVENT_LBUTTONDOWN:
|
||||
if state == STATE_TRUCK:
|
||||
points_truck.append([x, y])
|
||||
print(f"Truck Area - Point {len(points_truck)}: [{x}, {y}]")
|
||||
if len(points_truck) == 4:
|
||||
state = STATE_DETECTION
|
||||
print("\n-> Area Truk Berhasil Dipilih (4 titik).")
|
||||
print("-> SILAHKAN PILIH AREA DETEKSI (Klik Kiri 4 Titik secara berurutan: Top-Left, Top-Right, Bottom-Right, Bottom-Left).")
|
||||
elif state == STATE_DETECTION:
|
||||
points_detection.append([x, y])
|
||||
print(f"Detection Area - Point {len(points_detection)}: [{x}, {y}]")
|
||||
if len(points_detection) == 4:
|
||||
state = STATE_LINE
|
||||
print("\n-> Area Deteksi Berhasil Dipilih (4 titik).")
|
||||
print("-> SILAHKAN PILIH COUNT LINE (Klik Kiri Titik Mulai dan Titik Selesai).")
|
||||
elif state == STATE_LINE:
|
||||
points_line.append([x, y])
|
||||
print(f"Count Line - Point {len(points_line)}: [{x}, {y}]")
|
||||
if len(points_line) == 2:
|
||||
state = STATE_DONE
|
||||
print("\n-> Count Line Berhasil Dipilih.")
|
||||
print("-> Semua koordinat telah lengkap! Tekan 's' untuk mencetak & menyimpan koordinat.")
|
||||
|
||||
draw_frame()
|
||||
|
||||
def draw_frame():
|
||||
img_copy = img.copy()
|
||||
h, w, _ = img_copy.shape
|
||||
|
||||
# 1. Draw Area Truk (Orange Polygon)
|
||||
for pt in points_truck:
|
||||
cv2.circle(img_copy, tuple(pt), 5, (0, 165, 255), -1)
|
||||
if len(points_truck) == 4:
|
||||
pts = np.array(points_truck, np.int32)
|
||||
cv2.polylines(img_copy, [pts], True, (0, 165, 255), 2)
|
||||
cv2.putText(img_copy, "TRUCK AREA", tuple(points_truck[0]),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 165, 255), 1)
|
||||
|
||||
# 2. Draw Area Deteksi (Cyan Polygon)
|
||||
for pt in points_detection:
|
||||
cv2.circle(img_copy, tuple(pt), 5, (255, 255, 0), -1)
|
||||
if len(points_detection) == 4:
|
||||
pts = np.array(points_detection, np.int32)
|
||||
cv2.polylines(img_copy, [pts], True, (255, 255, 0), 2)
|
||||
cv2.putText(img_copy, "DETECTION AREA", tuple(points_detection[0]),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 0), 1)
|
||||
|
||||
# 3. Draw Count Line (Magenta Line)
|
||||
if len(points_line) > 0:
|
||||
cv2.circle(img_copy, tuple(points_line[0]), 5, (255, 0, 255), -1)
|
||||
if len(points_line) == 2:
|
||||
cv2.line(img_copy, tuple(points_line[0]), tuple(points_line[1]), (255, 0, 255), 3)
|
||||
# Draw midpoint circle
|
||||
mid_x = int((points_line[0][0] + points_line[1][0]) / 2)
|
||||
mid_y = int((points_line[0][1] + points_line[1][1]) / 2)
|
||||
cv2.circle(img_copy, (mid_x, mid_y), 6, (0, 255, 0), -1)
|
||||
cv2.putText(img_copy, f"LINE (y={mid_y})", (mid_x + 10, mid_y - 10),
|
||||
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 255), 1)
|
||||
|
||||
# Draw Instruction Overlay on Top
|
||||
overlay_y = 35
|
||||
if state == STATE_TRUCK:
|
||||
txt = f"1. PILIH AREA TRUK (Klik Kiri 4 Titik, saat ini: {len(points_truck)}/4)"
|
||||
color = (0, 165, 255)
|
||||
elif state == STATE_DETECTION:
|
||||
txt = f"2. PILIH AREA DETEKSI (Klik Kiri 4 Titik, saat ini: {len(points_detection)}/4)"
|
||||
color = (255, 255, 0)
|
||||
elif state == STATE_LINE:
|
||||
txt = f"3. PILIH COUNT LINE (Klik Kiri Titik Awal lalu Titik Akhir, saat ini: {len(points_line)}/2)"
|
||||
color = (255, 0, 255)
|
||||
else:
|
||||
txt = "SELESAI! Tekan 's' untuk simpan atau 'c' untuk ulang."
|
||||
color = (0, 255, 0)
|
||||
|
||||
# Draw background panel for text
|
||||
cv2.rectangle(img_copy, (10, 10), (w - 10, 50), (0, 0, 0), -1)
|
||||
cv2.putText(img_copy, txt, (20, overlay_y), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2)
|
||||
|
||||
cv2.imshow('Interactive 4-Point Zone Selector', img_copy)
|
||||
|
||||
if __name__ == "__main__":
|
||||
source_img = "gambar_terbaru.jpg" if os.path.exists("gambar_terbaru.jpg") else "calib_frame.jpg"
|
||||
video_source = "0727.mp4"
|
||||
|
||||
if os.path.exists(source_img):
|
||||
img = cv2.imread(source_img)
|
||||
print(f"Loaded image: {source_img}")
|
||||
elif os.path.exists(video_source):
|
||||
print(f"Grabbing frame from video: {video_source}")
|
||||
cap = cv2.VideoCapture(video_source)
|
||||
for _ in range(10):
|
||||
ret, img = cap.read()
|
||||
cap.release()
|
||||
if not ret:
|
||||
print("Error: Could not grab frame from video.")
|
||||
exit(1)
|
||||
else:
|
||||
print("Error: Neither calib_frame.jpg nor the video file exists.")
|
||||
exit(1)
|
||||
|
||||
cv2.namedWindow('Interactive 4-Point Zone Selector')
|
||||
cv2.setMouseCallback('Interactive 4-Point Zone Selector', click_event)
|
||||
|
||||
print("\n=== OpenCV 4-Point Zone Coordinate Selector ===")
|
||||
print("Instructions:")
|
||||
print("1. Left-click to select coordinates for each step.")
|
||||
print("2. Press 'c' at any time to clear selection and restart.")
|
||||
print("3. Press 's' when done to print python snippets and save to zones_output.json.")
|
||||
print("4. Press 'q' or 'ESC' to quit.")
|
||||
print("========================================\n")
|
||||
print("-> SILAHKAN PILIH AREA TRUK (Klik Kiri 4 Titik secara berurutan: Top-Left, Top-Right, Bottom-Right, Bottom-Left).")
|
||||
|
||||
draw_frame()
|
||||
|
||||
while True:
|
||||
key = cv2.waitKey(1) & 0xFF
|
||||
if key == ord('c') or key == ord('C'):
|
||||
state = STATE_TRUCK
|
||||
points_truck = []
|
||||
points_detection = []
|
||||
points_line = []
|
||||
print("\nCleared selection. Restarting from Step 1 (Area Truk)...")
|
||||
draw_frame()
|
||||
elif key == ord('s') or key == ord('S'):
|
||||
if state != STATE_DONE:
|
||||
print(f"Warning: Harap selesaikan semua langkah terlebih dahulu. State saat ini: {state}")
|
||||
continue
|
||||
|
||||
lx1, ly1 = points_line[0]
|
||||
lx2, ly2 = points_line[1]
|
||||
line_y_avg = int((ly1 + ly2) / 2)
|
||||
|
||||
output_data = {
|
||||
"truck_poly": points_truck,
|
||||
"detection_poly": points_detection,
|
||||
"count_line": {
|
||||
"x_start": lx1, "x_end": lx2, "y": line_y_avg
|
||||
}
|
||||
}
|
||||
|
||||
# Print configuration code snippets
|
||||
print("\n" + "="*50)
|
||||
print("KOORDINAT BERHASIL DI-GENERATE!")
|
||||
print("="*50)
|
||||
print("\n--- SALIN KODE DI BAWAH INI KE predict.py ---\n")
|
||||
print(f" # 1. Detection Area (4-point Polygon)")
|
||||
print(f" detection_poly_pts = [")
|
||||
for pt in points_detection:
|
||||
print(f" [int({pt[0]} * scale_x), int({pt[1]} * scale_y)],")
|
||||
print(f" ]")
|
||||
print(f" detection_polygon = Polygon(detection_poly_pts)")
|
||||
print()
|
||||
print(f" # 2. Count Line coordinates")
|
||||
print(f" static_line_y = int({line_y_avg} * scale_y)")
|
||||
print(f" static_line_x_start = int({lx1} * scale_x)")
|
||||
print(f" static_line_x_end = int({lx2} * scale_x)")
|
||||
print()
|
||||
print(f" # 3. Truck Area (4-point Polygon for presence check)")
|
||||
print(f" truck_poly_pts = [")
|
||||
for pt in points_truck:
|
||||
print(f" [int({pt[0]} * scale_x), int({pt[1]} * scale_y)],")
|
||||
print(f" ]")
|
||||
print(f" truck_polygon = Polygon(truck_poly_pts)")
|
||||
print()
|
||||
|
||||
# Calculate bounding box of truck_polygon to maintain backward compatibility with static_roi
|
||||
tx_coords = [p[0] for p in points_truck]
|
||||
ty_coords = [p[1] for p in points_truck]
|
||||
min_tx, max_tx = min(tx_coords), max(tx_coords)
|
||||
min_ty, max_ty = min(ty_coords), max(ty_coords)
|
||||
print(f" static_roi = TruckROI(")
|
||||
print(f" x1=int({min_tx} * scale_x),")
|
||||
print(f" y1=int({min_ty} * scale_y),")
|
||||
print(f" x2=int({max_tx} * scale_x),")
|
||||
print(f" y2=int({max_ty} * scale_y),")
|
||||
print(f" line_y=static_line_y,")
|
||||
print(f" confidence=1.0")
|
||||
print(f" )")
|
||||
print("\n" + "="*50)
|
||||
|
||||
# Save to json file
|
||||
with open("zones_output.json", "w") as f:
|
||||
json.dump(output_data, f, indent=4)
|
||||
print("Koordinat juga telah disimpan ke 'zones_output.json'\n")
|
||||
|
||||
elif key == ord('q') or key == 27:
|
||||
break
|
||||
|
||||
cv2.destroyAllWindows()
|
||||
Reference in new issue
Block a user