doinglean's picture
Update app.py
29e9e8c verified
import gradio as gr
from huggingface_hub import hf_hub_download
from ultralytics import YOLO
import cv2
import numpy as np
import easyocr
import logging
# Logging einrichten
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Lade das Modell
model_path = hf_hub_download(repo_id="foduucom/stockmarket-pattern-detection-yolov8", filename="model.pt")
model = YOLO(model_path)
# OCR für Preise
reader = easyocr.Reader(['en'], gpu=False)
def analyze_image(image, prompt):
logger.info("Starting image analysis with prompt: %s", prompt)
# Konvertiere PIL-Bild zu OpenCV-Format
image_np = np.array(image)
image_cv = cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)
# Bildvorverarbeitung: Kontrast erhöhen
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
gray = cv2.cvtColor(image_cv, cv2.COLOR_BGR2GRAY)
enhanced = clahe.apply(gray)
image_cv = cv2.cvtColor(enhanced, cv2.COLOR_GRAY2BGR)
logger.info("Image preprocessed: shape=%s", image_np.shape)
# Führe Objekterkennung durch
results = model.predict(source=image_np, conf=0.3, iou=0.5, save=False)
logger.info("YOLO predictions: %d boxes detected", len(results[0].boxes))
# Extrahiere Kerzen
detections = []
for result in results:
for box in result.boxes:
label = result.names[int(box.cls)]
confidence = float(box.conf)
xmin, ymin, xmax, ymax = box.xyxy[0].tolist()
logger.info("Detected: %s, confidence=%.2f, box=(%.0f, %.0f, %.0f, %.0f)",
label, confidence, xmin, ymin, xmax, ymax)
# Extrahiere Farbe (Fokus auf Kerzenkörper)
candle_roi = image_cv[int(ymin):int(ymax), int(xmin):int(xmax)]
if candle_roi.size == 0:
logger.warning("Empty ROI for box: (%.0f, %.0f, %.0f, %.0f)", xmin, ymin, xmax, ymax)
continue
mean_color = np.mean(candle_roi, axis=(0, 1)).astype(int)
color_rgb = f"RGB({mean_color[2]},{mean_color[1]},{mean_color[0]})"
# OCR für Preise (erweitere ROI für Achsen)
price_roi = image_cv[max(0, int(ymin)-50):min(image_np.shape[0], int(ymax)+50),
max(0, int(xmin)-50):min(image_np.shape[1], int(xmax)+50)]
price_text = reader.readtext(price_roi, detail=0, allowlist='0123456789.')
prices = ' '.join(price_text) if price_text else "No price detected"
logger.info("OCR prices: %s", prices)
detections.append({
"pattern": label,
"confidence": confidence,
"color": color_rgb,
"prices": prices,
"x_center": (xmin + xmax) / 2
})
# Sortiere nach x-Position (rechts nach links = neueste Kerzen)
detections = sorted(detections, key=lambda x: x["x_center"], reverse=True)
logger.info("Sorted detections: %d", len(detections))
# Begrenze auf die letzten 8 Kerzen
if "last 8 candles" in prompt.lower() or "letzte 8 kerzen" in prompt.lower():
detections = detections[:8]
# Debugging: Wenn leer, gib Hinweis
if not detections:
logger.warning("No detections found. Check image quality or model configuration.")
return {"prompt": prompt, "description": "No candlesticks detected. Ensure clear image and visible candles."}
return {
"prompt": prompt,
"detections": detections
}
# Erstelle Gradio-Schnittstelle
iface = gr.Interface(
fn=analyze_image,
inputs=[
gr.Image(type="pil", label="Upload TradingView Screenshot"),
gr.Textbox(label="Prompt", placeholder="Enter your prompt, e.g., 'List last 8 candles with their colors'")
],
outputs="json",
title="Stock Chart Analysis with YOLOv8",
description="Upload a TradingView screenshot to detect the last 8 candlesticks, their colors, and prices."
)
iface.launch()