Enhance image before ai processing
Build, push image, and notify Watchtower / build-image (push) Successful in 41s
Build, push image, and notify Watchtower / notify (push) Successful in 14s

This commit is contained in:
2026-08-23 12:33:39 +02:00
parent 6b8c1688a6
commit 3711928c7d
3 changed files with 63 additions and 3 deletions
+24 -3
View File
@@ -17,6 +17,7 @@ from APIs.mqtt import send_command
from APIs.webex import WebexManager from APIs.webex import WebexManager
from APIs.shodan import ShodanAuditor from APIs.shodan import ShodanAuditor
from APIs.twilio import send_alert_sms from APIs.twilio import send_alert_sms
from cloud.image_enhancer import enhance_image_for_ai
from microwaveCookPlanner import MicrowaveCookPlanner from microwaveCookPlanner import MicrowaveCookPlanner
import safety_checker import safety_checker
from jobs import job_server_cve_audit, job_client_ip_audit, job_request_telemetry from jobs import job_server_cve_audit, job_client_ip_audit, job_request_telemetry
@@ -153,7 +154,7 @@ start_scheduler_once()
# --------------------------------------------------------- # ---------------------------------------------------------
# Authentication Middleware # Authentication Middleware
# --------------------------------------------------------- # ---------------------------------------------------------
EXEMPT_ROUTES = {'hello_world', 'oauth_callback', 'odata_metadata', 'debug_telemetryrequest', 'trigger_job_manually'} EXEMPT_ROUTES = {'hello_world', 'oauth_callback', 'odata_metadata', 'debug_telemetryrequest', 'trigger_job_manually', 'debug_unsafe_dish', 'debug_safe_dish'}
@app.before_request @app.before_request
def authenticate_request(): def authenticate_request():
@@ -245,12 +246,14 @@ async def cooking_params():
with open(filepath, "wb") as f: with open(filepath, "wb") as f:
f.write(base64.b64decode(camera_image_b64)) f.write(base64.b64decode(camera_image_b64))
data["camera_image"] = filepath data["camera_image"] = filepath
enhanced_filepath = enhance_image_for_ai(filepath)
# Concurrent AI Execution # Concurrent AI Execution
safety_task = asyncio.to_thread(safety_checker.check_dish_safety, filepath) safety_task = asyncio.to_thread(safety_checker.check_dish_safety, enhanced_filepath)
planner_task = asyncio.to_thread( planner_task = asyncio.to_thread(
microwave_cook_planner.generate_plan, microwave_cook_planner.generate_plan,
image_path=filepath, image_path=enhanced_filepath,
height_cm=height_cm, height_cm=height_cm,
initial_temp_c=initial_temp_c, initial_temp_c=initial_temp_c,
microwave_wattage=microwave_wattage, microwave_wattage=microwave_wattage,
@@ -584,6 +587,24 @@ def trigger_job_manually(job_id):
"status": "error", "status": "error",
"message": f"Job execution failed: {str(e)}" "message": f"Job execution failed: {str(e)}"
}), 500 }), 500
@app.route("/debug/dishsafety/not_safe", methods=["GET"])
def debug_unsafe_dish():
"""Debug endpoint to simulate an unsafe dish scenario."""
# Simulated unsafe dish data
unsafe_dish = "storage/dishPhotos/dish_78827473286c4f67855f3fbd0ccb9bb4.jpg"
# Call the cooking_params endpoint logic directly
return safety_checker.check_dish_safety(unsafe_dish)
@app.route("/debug/dishsafety/safe", methods=["GET"])
def debug_safe_dish():
"""Debug endpoint to simulate a safe dish scenario."""
# Simulated safe dish data
unsafe_dish = "storage/dishPhotos/dish_972251744d034b32bb5134ff9d0f071c.jpg"
# Call the cooking_params endpoint logic directly
return safety_checker.check_dish_safety(unsafe_dish)
# --------------------------------------------------------- # ---------------------------------------------------------
# OData Metadata Definition # OData Metadata Definition
+23
View File
@@ -0,0 +1,23 @@
import cv2
def enhance_image_for_ai(input_path: str) -> str:
"""Enhances dark areas and contrast using CLAHE without blowing out bright areas."""
img = cv2.imread(input_path)
if img is None:
return input_path
# Convert to LAB color space to modify luminance channel only
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
l, a, b = cv2.split(lab)
# Apply CLAHE to Lightness channel
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8))
cl = clahe.apply(l)
# Merge channels and convert back to BGR
limg = cv2.merge((cl, a, b))
enhanced = cv2.cvtColor(limg, cv2.COLOR_LAB2BGR)
enhanced_path = input_path.replace(".jpg", "_enhanced.jpg")
cv2.imwrite(enhanced_path, enhanced)
return enhanced_path
+16
View File
@@ -2,6 +2,7 @@ import json
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from APIs.aichat import generate from APIs.aichat import generate
import shared.config as config import shared.config as config
from PIL import Image, ImageEnhance
class UtensilMaterialCheck(BaseModel): class UtensilMaterialCheck(BaseModel):
object_name: str = Field( object_name: str = Field(
@@ -28,6 +29,21 @@ class DishSafetyResult(BaseModel):
description="If is_safe is False, set to 'REMOVE METAL UTENSIL OR FOIL BEFORE MICROWAVING'. Otherwise empty ''." description="If is_safe is False, set to 'REMOVE METAL UTENSIL OR FOIL BEFORE MICROWAVING'. Otherwise empty ''."
) )
def preprocess_dish_image(image_path: str) -> str:
"""Brightens dark areas and sharpens food texture for small vision models."""
img = Image.open(image_path)
# 1. Boost brightness slightly
enhancer = ImageEnhance.Brightness(img)
img = enhancer.enhance(1.4)
# 2. Boost contrast to separate food shapes from dark shadows
enhancer = ImageEnhance.Contrast(img)
img = enhancer.enhance(1.3)
processed_path = "/tmp/processed_dish.jpg"
img.save(processed_path, quality=85)
return processed_path
def check_dish_safety(image_path: str) -> dict: def check_dish_safety(image_path: str) -> dict:
prompt = ( prompt = (