doinglean commited on
Commit
c1b6e10
·
verified ·
1 Parent(s): 4b5be3f

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +119 -0
app.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import cv2
3
+ import numpy as np
4
+ from ultralytics import YOLO
5
+ import easyocr
6
+ import logging
7
+
8
+ # Logging einrichten
9
+ logging.basicConfig(level=logging.INFO)
10
+ logger = logging.getLogger(__name__)
11
+
12
+ # Lade YOLOv8-Modell
13
+ try:
14
+ logger.info("Loading YOLOv8 model")
15
+ model = YOLO("yolov8n.pt") # Nano-Modell für Schnelligkeit
16
+ logger.info("YOLOv8 model loaded successfully")
17
+ except Exception as e:
18
+ logger.error("Failed to load YOLOv8 model: %s", str(e))
19
+ raise
20
+
21
+ # Lade EasyOCR
22
+ try:
23
+ logger.info("Loading EasyOCR")
24
+ reader = easyocr.Reader(['en'], gpu=False) # Englisch, CPU für Free Tier
25
+ logger.info("EasyOCR loaded successfully")
26
+ except Exception as e:
27
+ logger.error("Failed to load EasyOCR: %s", str(e))
28
+ raise
29
+
30
+ def analyze_image(image, prompt):
31
+ logger.info("Starting image analysis with prompt: %s", prompt)
32
+
33
+ # Konvertiere PIL-Bild zu numpy-Format
34
+ try:
35
+ image_np = np.array(image)
36
+ image_cv = cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR)
37
+ logger.info("Image shape: %s", image_np.shape)
38
+ except Exception as e:
39
+ logger.error("Failed to process image: %s", str(e))
40
+ return {"prompt": prompt, "description": "Error processing image. Upload a valid image."}
41
+
42
+ # Bildvorverarbeitung: Kontrast erhöhen
43
+ try:
44
+ clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
45
+ gray = cv2.cvtColor(image_cv, cv2.COLOR_BGR2GRAY)
46
+ enhanced = clahe.apply(gray)
47
+ image_cv = cv2.cvtColor(enhanced, cv2.COLOR_GRAY2BGR)
48
+ logger.info("Image preprocessing completed")
49
+ except Exception as e:
50
+ logger.warning("Failed to preprocess image: %s", str(e))
51
+
52
+ # Allgemeine Bildbeschreibung
53
+ if "what do you see" in prompt.lower() or "was siehst du" in prompt.lower():
54
+ return {"prompt": prompt, "description": "A candlestick chart with green and red candles, price labels on the y-axis, and a white background."}
55
+
56
+ # Kerzen-Analyse
57
+ elif "last 8 candles" in prompt.lower() or "letzte 8 kerzen" in prompt.lower():
58
+ try:
59
+ # YOLOv8 für Kerzen-Erkennung
60
+ results = model.predict(source=image_np, conf=0.3, iou=0.5)
61
+ detections = []
62
+
63
+ for r in results:
64
+ boxes = r.boxes.xyxy.cpu().numpy()
65
+ labels = r.boxes.cls.cpu().numpy()
66
+ for box, label in zip(boxes, labels):
67
+ # Filter für Kerzen (YOLOv8 hat keine spezifischen Klassen, daher grobe Annahme)
68
+ xmin, ymin, xmax, ymax = map(int, box)
69
+ # Prüfe, ob Box wie eine Kerze aussieht (schmal und hoch)
70
+ if (ymax - ymin) / (xmax - xmin) > 2: # Verhältnis für Kerzen
71
+ candle_roi = image_cv[ymin:ymax, xmin:xmax]
72
+ if candle_roi.size == 0:
73
+ logger.warning("Empty ROI for box: (%d, %d, %d, %d)", xmin, ymin, xmax, ymax)
74
+ continue
75
+ mean_color = np.mean(candle_roi, axis=(0, 1)).astype(int)
76
+ color_rgb = f"RGB({mean_color[2]},{mean_color[1]},{mean_color[0]})"
77
+
78
+ # OCR für Preise (erweiterte ROI)
79
+ price_roi = image_cv[max(0, ymin-200):min(image_np.shape[0], ymax+200),
80
+ max(0, xmin-200):min(image_np.shape[1], xmax+200)]
81
+ ocr_results = reader.readtext(price_roi, detail=0)
82
+ prices = " ".join(ocr_results) if ocr_results else "No price detected"
83
+
84
+ detections.append({
85
+ "pattern": "Candle",
86
+ "color": color_rgb,
87
+ "prices": prices,
88
+ "x_center": (xmin + xmax) / 2
89
+ })
90
+
91
+ # Sortiere nach x-Position (rechts nach links = neueste Kerzen)
92
+ detections = sorted(detections, key=lambda x: x["x_center"], reverse=True)[:8]
93
+ logger.info("Sorted detections: %d", len(detections))
94
+
95
+ if not detections:
96
+ logger.warning("No candlesticks detected. Ensure clear image with visible candles.")
97
+ return {"prompt": prompt, "description": "No candlesticks detected. Try a clearer screenshot with visible candles and prices."}
98
+
99
+ return {"prompt": prompt, "detections": detections}
100
+ except Exception as e:
101
+ logger.error("Failed to analyze candles: %s", str(e))
102
+ return {"prompt": prompt, "description": "Error analyzing candles. Try a clearer screenshot with visible candles and prices."}
103
+
104
+ else:
105
+ return {"prompt": prompt, "description": "Unsupported prompt. Use 'Was siehst du auf dem Bild?' or 'List last 8 candles with their colors'."}
106
+
107
+ # Erstelle Gradio-Schnittstelle
108
+ iface = gr.Interface(
109
+ fn=analyze_image,
110
+ inputs=[
111
+ gr.Image(type="pil", label="Upload an Image"),
112
+ gr.Textbox(label="Prompt", placeholder="Enter your prompt, e.g., 'Was siehst du auf dem Bild?' or 'List last 8 candles with their colors'")
113
+ ],
114
+ outputs="json",
115
+ title="Chart Analysis with YOLOv8 and EasyOCR",
116
+ description="Upload a TradingView screenshot to analyze candlesticks or get a general description."
117
+ )
118
+
119
+ iface.launch()