92 lines
3.5 KiB
Python
92 lines
3.5 KiB
Python
"""
|
|
Native Desktop GUI for Supermarket Shelf Product Recognition
|
|
Opens a desktop OpenCV window displaying image.jpg with bounding boxes only.
|
|
Users can click on any product directly on screen to inspect price, stock,
|
|
and feature matching inliers in real-time.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import cv2
|
|
import numpy as np
|
|
|
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
if current_dir not in sys.path:
|
|
sys.path.insert(0, current_dir)
|
|
|
|
from pipeline import ShelfRecognitionPipeline
|
|
|
|
|
|
def main():
|
|
print("=" * 60)
|
|
print("STARTING NATIVE DESKTOP INTERFACE")
|
|
print("Image: image.jpg | Mode: Hybrid (Paper Method)")
|
|
print("Instructions: Click on ANY product to identify & view info.")
|
|
print("Press 'q' or 'ESC' on the window to exit.")
|
|
print("=" * 60)
|
|
|
|
pipeline = ShelfRecognitionPipeline()
|
|
init_res = pipeline.set_active_shelf_image("image.jpg")
|
|
|
|
if init_res.get("status") != "success":
|
|
print("[Error] Failed to load image.jpg")
|
|
return
|
|
|
|
boxes = init_res["boxes"]
|
|
base_image = pipeline.current_image.copy()
|
|
|
|
# Draw ONLY bounding boxes (no class names, no confidence labels)
|
|
display_image = pipeline.detector.draw_detections(base_image, boxes, draw_labels=False)
|
|
|
|
window_name = "Smart Shelf - Click Any Product (Press Q to quit)"
|
|
cv2.namedWindow(window_name, cv2.WINDOW_NORMAL)
|
|
cv2.resizeWindow(window_name, 1280, 850)
|
|
|
|
def on_mouse(event, x, y, flags, param):
|
|
if event == cv2.EVENT_LBUTTONDOWN:
|
|
print(f"\n[Click detected at coordinates: ({x}, {y})]")
|
|
res = pipeline.process_click(x, y, method="hybrid")
|
|
|
|
if res.get("status") == "success":
|
|
prod = res["inventory"]
|
|
cls_info = res["classification"]
|
|
box_info = res["target_box"]
|
|
|
|
print("-" * 55)
|
|
print(f"📦 Product Identified : {prod['product_name']}")
|
|
print(f"🏷️ SKU ID : {prod['sku_id']}")
|
|
print(f"💰 Price : ¥{prod['price']}")
|
|
print(f"📊 In Stock (On-Shelf): {prod['number_on']} units")
|
|
print(f"🚚 Received / Sold : {prod['number_in']} in / {prod['number_out']} out")
|
|
print(f"📅 Expiration Date : {prod['expiration_date']}")
|
|
print(f"🎯 Match Confidence : {cls_info['confidence'] * 100:.1f}% (Score: {cls_info['score']})")
|
|
print("-" * 55)
|
|
|
|
# Update main window with selected box highlight (in red)
|
|
selected_display = pipeline.detector.draw_detections(
|
|
base_image, boxes, selected_box_id=box_info["id"], draw_labels=False
|
|
)
|
|
cv2.imshow(window_name, selected_display)
|
|
|
|
# Show visual match comparison window if available
|
|
if res.get("match_visualization") is not None:
|
|
match_win = "Feature Matcher (Shelf Crop vs Stock Template)"
|
|
cv2.namedWindow(match_win, cv2.WINDOW_NORMAL)
|
|
cv2.resizeWindow(match_win, 800, 400)
|
|
cv2.imshow(match_win, res["match_visualization"])
|
|
else:
|
|
print(f"[Info] {res.get('message', 'No product found at coordinates.')}")
|
|
|
|
cv2.setMouseCallback(window_name, on_mouse)
|
|
|
|
while True:
|
|
cv2.imshow(window_name, display_image)
|
|
key = cv2.waitKey(20) & 0xFF
|
|
if key in [ord('q'), ord('Q'), 27]:
|
|
break
|
|
|
|
cv2.destroyAllWindows()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|