Update app.py
Browse files
app.py
CHANGED
|
@@ -28,7 +28,7 @@ app = FastAPI(
|
|
| 28 |
HF_TOKEN = os.getenv("HF_TOKEN", "")
|
| 29 |
HF_DATASET_ID = os.getenv("HF_DATASET_ID", "Fred808/BG3") # Source dataset with zips
|
| 30 |
HF_OUTPUT_DATASET_ID = os.getenv("HF_OUTPUT_DATASET_ID", "Fred808/data") # Results dataset
|
| 31 |
-
HF_STATE_FILE = os.getenv("HF_STATE_FILE", "
|
| 32 |
TEMP_DATASET_DIR = Path("temp_cursor_detection")
|
| 33 |
TEMP_DATASET_DIR.mkdir(exist_ok=True)
|
| 34 |
|
|
@@ -279,17 +279,26 @@ class DatasetProgress:
|
|
| 279 |
# Global progress tracker
|
| 280 |
dataset_progress = DatasetProgress()
|
| 281 |
|
| 282 |
-
async def process_image(
|
| 283 |
"""Process a single image and return cursor detection results."""
|
| 284 |
try:
|
| 285 |
-
|
| 286 |
-
frame = cv2.
|
| 287 |
-
|
| 288 |
if frame is None:
|
| 289 |
-
raise ValueError("Could not
|
| 290 |
|
|
|
|
|
|
|
|
|
|
| 291 |
pos, conf, template_name = detect_cursor_in_frame_multi(frame, CURSOR_TEMPLATES, threshold)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 292 |
|
|
|
|
| 293 |
confidence = float(conf)
|
| 294 |
if confidence == float('inf') or confidence == float('-inf'):
|
| 295 |
confidence = 1.0 if confidence > 0 else 0.0
|
|
@@ -303,7 +312,8 @@ async def process_image(image_bytes: bytes, threshold: float = 0.8) -> dict:
|
|
| 303 |
'image_shape': list(frame.shape)
|
| 304 |
}
|
| 305 |
except Exception as e:
|
| 306 |
-
|
|
|
|
| 307 |
|
| 308 |
async def dataset_task(start_index: int = 1):
|
| 309 |
"""Main dataset processing loop for processing zip files."""
|
|
@@ -376,17 +386,26 @@ async def dataset_task(start_index: int = 1):
|
|
| 376 |
|
| 377 |
# Process all images in the zip
|
| 378 |
results = []
|
| 379 |
-
|
|
|
|
|
|
|
| 380 |
try:
|
| 381 |
-
with open(image_path, 'rb') as f:
|
| 382 |
-
content = f.read()
|
| 383 |
-
|
| 384 |
# Process image for cursor detection
|
| 385 |
-
|
|
|
|
|
|
|
|
|
|
| 386 |
image_result['image_name'] = image_path.name
|
| 387 |
image_result['image_path'] = str(image_path.relative_to(extract_dir))
|
|
|
|
| 388 |
results.append(image_result)
|
| 389 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 390 |
except Exception as e:
|
| 391 |
print(f"[DATASET] Error processing {image_path.name}: {e}")
|
| 392 |
continue
|
|
@@ -446,6 +465,15 @@ async def dataset_task(start_index: int = 1):
|
|
| 446 |
@app.on_event("startup")
|
| 447 |
async def startup_event():
|
| 448 |
"""Load templates when the application starts."""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 449 |
load_cursor_templates()
|
| 450 |
|
| 451 |
@app.post('/start_dataset')
|
|
@@ -500,9 +528,30 @@ async def track_cursor_endpoint(
|
|
| 500 |
detail="Cursor templates are not loaded."
|
| 501 |
)
|
| 502 |
|
| 503 |
-
|
| 504 |
-
|
| 505 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 506 |
|
| 507 |
@app.post("/track_cursor_url")
|
| 508 |
async def track_cursor_url_endpoint(
|
|
|
|
| 28 |
HF_TOKEN = os.getenv("HF_TOKEN", "")
|
| 29 |
HF_DATASET_ID = os.getenv("HF_DATASET_ID", "Fred808/BG3") # Source dataset with zips
|
| 30 |
HF_OUTPUT_DATASET_ID = os.getenv("HF_OUTPUT_DATASET_ID", "Fred808/data") # Results dataset
|
| 31 |
+
HF_STATE_FILE = os.getenv("HF_STATE_FILE", "processing_state_cursors.json")
|
| 32 |
TEMP_DATASET_DIR = Path("temp_cursor_detection")
|
| 33 |
TEMP_DATASET_DIR.mkdir(exist_ok=True)
|
| 34 |
|
|
|
|
| 279 |
# Global progress tracker
|
| 280 |
dataset_progress = DatasetProgress()
|
| 281 |
|
| 282 |
+
async def process_image(image_path: Path, threshold: float = 0.8) -> dict:
|
| 283 |
"""Process a single image and return cursor detection results."""
|
| 284 |
try:
|
| 285 |
+
# Read image with OpenCV directly
|
| 286 |
+
frame = cv2.imread(str(image_path), cv2.IMREAD_UNCHANGED)
|
|
|
|
| 287 |
if frame is None:
|
| 288 |
+
raise ValueError(f"Could not read image: {image_path}")
|
| 289 |
|
| 290 |
+
print(f"[DETECT] Processing image {image_path.name}, shape: {frame.shape}")
|
| 291 |
+
|
| 292 |
+
# Run cursor detection
|
| 293 |
pos, conf, template_name = detect_cursor_in_frame_multi(frame, CURSOR_TEMPLATES, threshold)
|
| 294 |
+
|
| 295 |
+
# Log detection result
|
| 296 |
+
if pos is not None:
|
| 297 |
+
print(f"[DETECT] Found cursor in {image_path.name} at {pos} using template {template_name} (conf: {conf:.3f})")
|
| 298 |
+
else:
|
| 299 |
+
print(f"[DETECT] No cursor found in {image_path.name} (best conf: {conf:.3f})")
|
| 300 |
|
| 301 |
+
# Handle confidence values
|
| 302 |
confidence = float(conf)
|
| 303 |
if confidence == float('inf') or confidence == float('-inf'):
|
| 304 |
confidence = 1.0 if confidence > 0 else 0.0
|
|
|
|
| 312 |
'image_shape': list(frame.shape)
|
| 313 |
}
|
| 314 |
except Exception as e:
|
| 315 |
+
print(f"[ERROR] Failed to process {image_path.name}: {str(e)}")
|
| 316 |
+
raise ValueError(f"Error processing image {image_path.name}: {str(e)}")
|
| 317 |
|
| 318 |
async def dataset_task(start_index: int = 1):
|
| 319 |
"""Main dataset processing loop for processing zip files."""
|
|
|
|
| 386 |
|
| 387 |
# Process all images in the zip
|
| 388 |
results = []
|
| 389 |
+
print(f"[DATASET] Starting cursor detection on {len(image_paths)} images...")
|
| 390 |
+
|
| 391 |
+
for i, image_path in enumerate(image_paths, 1):
|
| 392 |
try:
|
|
|
|
|
|
|
|
|
|
| 393 |
# Process image for cursor detection
|
| 394 |
+
print(f"[DATASET] Processing image {i}/{len(image_paths)}: {image_path.name}")
|
| 395 |
+
image_result = await process_image(image_path)
|
| 396 |
+
|
| 397 |
+
# Add file information
|
| 398 |
image_result['image_name'] = image_path.name
|
| 399 |
image_result['image_path'] = str(image_path.relative_to(extract_dir))
|
| 400 |
+
|
| 401 |
results.append(image_result)
|
| 402 |
|
| 403 |
+
# Log result
|
| 404 |
+
if image_result['cursor_active']:
|
| 405 |
+
print(f"[DATASET] ✓ Found cursor in {image_path.name}")
|
| 406 |
+
else:
|
| 407 |
+
print(f"[DATASET] ✗ No cursor found in {image_path.name}")
|
| 408 |
+
|
| 409 |
except Exception as e:
|
| 410 |
print(f"[DATASET] Error processing {image_path.name}: {e}")
|
| 411 |
continue
|
|
|
|
| 465 |
@app.on_event("startup")
|
| 466 |
async def startup_event():
|
| 467 |
"""Load templates when the application starts."""
|
| 468 |
+
if not CURSOR_TEMPLATES_DIR.exists():
|
| 469 |
+
print(f"Creating cursor templates directory: {CURSOR_TEMPLATES_DIR}")
|
| 470 |
+
CURSOR_TEMPLATES_DIR.mkdir(parents=True, exist_ok=True)
|
| 471 |
+
|
| 472 |
+
if not list(CURSOR_TEMPLATES_DIR.glob('*.png')):
|
| 473 |
+
print("WARNING: No cursor template files found in cursors directory!")
|
| 474 |
+
print(f"Please add cursor template PNG files to: {CURSOR_TEMPLATES_DIR}")
|
| 475 |
+
print("The server will start but cursor detection will not work without templates.")
|
| 476 |
+
|
| 477 |
load_cursor_templates()
|
| 478 |
|
| 479 |
@app.post('/start_dataset')
|
|
|
|
| 528 |
detail="Cursor templates are not loaded."
|
| 529 |
)
|
| 530 |
|
| 531 |
+
try:
|
| 532 |
+
# Save uploaded file to temporary path
|
| 533 |
+
temp_file = TEMP_DATASET_DIR / "temp_image"
|
| 534 |
+
temp_file.parent.mkdir(parents=True, exist_ok=True)
|
| 535 |
+
|
| 536 |
+
content = await file.read()
|
| 537 |
+
with open(temp_file, 'wb') as f:
|
| 538 |
+
f.write(content)
|
| 539 |
+
|
| 540 |
+
# Process image
|
| 541 |
+
results = await process_image(temp_file, threshold)
|
| 542 |
+
|
| 543 |
+
# Cleanup
|
| 544 |
+
try:
|
| 545 |
+
os.remove(temp_file)
|
| 546 |
+
except Exception:
|
| 547 |
+
pass
|
| 548 |
+
|
| 549 |
+
return JSONResponse(content=results)
|
| 550 |
+
except Exception as e:
|
| 551 |
+
raise HTTPException(
|
| 552 |
+
status_code=500,
|
| 553 |
+
detail=f"Error processing image: {str(e)}"
|
| 554 |
+
)
|
| 555 |
|
| 556 |
@app.post("/track_cursor_url")
|
| 557 |
async def track_cursor_url_endpoint(
|