doinglean commited on
Commit
c7ca595
·
verified ·
1 Parent(s): d0e76dd

Update app.py

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