tejovk311 commited on
Commit
ef5e09b
·
verified ·
1 Parent(s): a99dbb2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +1 -1105
app.py CHANGED
@@ -166,162 +166,6 @@ def vitals_data():
166
  response = requests.get(url, headers=headers, params=params)
167
  return jsonify(response.json()) if response.status_code == 200 else jsonify({"error": response.text}), 500
168
 
169
- # @app.route('/dashboard')
170
- # def dashboard():
171
- # html = '''
172
- # <!DOCTYPE html>
173
- # <html>
174
- # <head>
175
- # <title>Vitals Dashboard</title>
176
- # <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
177
- # <style>
178
- # body {
179
- # font-family: Arial, sans-serif;
180
- # padding: 10px;
181
- # background: #f4f6f9;
182
- # margin: 0;
183
- # }
184
- # h2 {
185
- # text-align: center;
186
- # margin-bottom: 10px;
187
- # }
188
- # .input-container {
189
- # text-align: center;
190
- # margin-bottom: 15px;
191
- # }
192
- # input, button {
193
- # padding: 8px;
194
- # font-size: 14px;
195
- # margin: 5px;
196
- # }
197
- # .grid-container {
198
- # display: grid;
199
- # grid-template-columns: 1fr 1fr;
200
- # gap: 10px;
201
- # }
202
- # .chart-box {
203
- # background: #fff;
204
- # border-radius: 8px;
205
- # padding: 5px;
206
- # box-shadow: 0 1px 6px rgba(0,0,0,0.1);
207
- # height: 300px;
208
- # }
209
- # </style>
210
- # </head>
211
- # <body>
212
- # <h2>Vitals Dashboard (Filter by MRD)</h2>
213
- # <div class="input-container">
214
- # <input type="text" id="mrd" placeholder="Enter MRD number" />
215
- # <button onclick="loadData()">Load</button>
216
- # </div>
217
- # <div class="grid-container">
218
- # <div class="chart-box" id="hr_chart"></div>
219
- # <div class="chart-box" id="rr_chart"></div>
220
- # <div class="chart-box" id="spo2_chart"></div>
221
- # <div class="chart-box" id="bp_chart"></div>
222
- # </div>
223
- # <script>
224
- # async function loadData() {
225
- # const mrd = document.getElementById("mrd").value.trim();
226
- # if (!mrd) return alert("Please enter an MRD number.");
227
- # const res = await fetch(`/vitals_data?mrd=${mrd}`);
228
- # const data = await res.json();
229
- # const timestamps = [], hr = [], rr = [], spo2 = [], sys = [], dia = [];
230
- # for (let v of data) {
231
- # timestamps.push(v.timestamp);
232
- # hr.push(v.heart_rate);
233
- # rr.push(v.respiratory_rate);
234
- # spo2.push(v.oxygen_saturation);
235
- # if (v.blood_pressure && v.blood_pressure.includes("/")) {
236
- # const [s, d] = v.blood_pressure.split("/");
237
- # sys.push(parseInt(s));
238
- # dia.push(parseInt(d));
239
- # } else {
240
- # sys.push(null);
241
- # dia.push(null);
242
- # }
243
- # }
244
-
245
- # // Layouts with fixed y-axis ranges
246
- # const layoutHR = {
247
- # title: "Heart Rate",
248
- # height: 280,
249
- # margin: { t: 30, l: 40, r: 20, b: 40 },
250
- # xaxis: { title: "Time", tickangle: -45 },
251
- # yaxis: { title: "bpm", range: [40, 130] }
252
- # };
253
-
254
- # const layoutRR = {
255
- # title: "Respiratory Rate",
256
- # height: 280,
257
- # margin: { t: 30, l: 40, r: 20, b: 40 },
258
- # xaxis: { title: "Time", tickangle: -45 },
259
- # yaxis: { title: "breaths/min", range: [5, 30] }
260
- # };
261
-
262
- # const layoutSpO2 = {
263
- # title: "Oxygen Saturation",
264
- # height: 280,
265
- # margin: { t: 30, l: 40, r: 20, b: 40 },
266
- # xaxis: { title: "Time", tickangle: -45 },
267
- # yaxis: { title: "%", range: [60, 100] }
268
- # };
269
-
270
- # const layoutBP = {
271
- # title: "Blood Pressure",
272
- # height: 280,
273
- # margin: { t: 30, l: 40, r: 20, b: 40 },
274
- # xaxis: { title: "Time", tickangle: -45 },
275
- # yaxis: { title: "mmHg", range: [40, 200] }
276
- # };
277
-
278
- # Plotly.newPlot("hr_chart", [{
279
- # x: timestamps,
280
- # y: hr,
281
- # name: "Heart Rate",
282
- # type: "scatter",
283
- # mode: "lines+markers"
284
- # }], layoutHR);
285
-
286
- # Plotly.newPlot("rr_chart", [{
287
- # x: timestamps,
288
- # y: rr,
289
- # name: "Respiratory Rate",
290
- # type: "scatter",
291
- # mode: "lines+markers"
292
- # }], layoutRR);
293
-
294
- # Plotly.newPlot("spo2_chart", [{
295
- # x: timestamps,
296
- # y: spo2,
297
- # name: "Oxygen Saturation",
298
- # type: "scatter",
299
- # mode: "lines+markers"
300
- # }], layoutSpO2);
301
-
302
- # Plotly.newPlot("bp_chart", [
303
- # {
304
- # x: timestamps,
305
- # y: sys,
306
- # name: "Systolic",
307
- # type: "scatter",
308
- # mode: "lines+markers"
309
- # },
310
- # {
311
- # x: timestamps,
312
- # y: dia,
313
- # name: "Diastolic",
314
- # type: "scatter",
315
- # mode: "lines+markers"
316
- # }
317
- # ], layoutBP);
318
- # }
319
- # </script>
320
- # </body>
321
- # </html>
322
- # '''
323
- # return render_template_string(html)
324
-
325
 
326
  @app.route('/dashboard')
327
  def dashboard():
@@ -470,952 +314,4 @@ def dashboard():
470
 
471
 
472
  if __name__ == '__main__':
473
- app.run(host='0.0.0.0', port=7860)
474
-
475
- # # # # # from flask import Flask, request, send_from_directory, render_template_string
476
- # # # # # import os
477
- # # # # # from datetime import datetime
478
-
479
- # # # # # app = Flask(__name__)
480
- # # # # # UPLOAD_FOLDER = '/tmp/received_images'
481
- # # # # # os.makedirs(UPLOAD_FOLDER, exist_ok=True)
482
-
483
- # # # # # latest_filename = None # Store the latest uploaded filename globally
484
-
485
- # # # # # @app.route('/upload', methods=['POST'])
486
- # # # # # def upload_file():
487
- # # # # # global latest_filename
488
- # # # # # img_data = request.data
489
- # # # # # filename = datetime.now().strftime("%Y%m%d_%H%M%S") + ".jpeg"
490
- # # # # # filepath = os.path.join(UPLOAD_FOLDER, filename)
491
- # # # # # with open(filepath, 'wb') as f:
492
- # # # # # f.write(img_data)
493
- # # # # # latest_filename = filename
494
- # # # # # return 'OK', 200
495
-
496
- # # # # # @app.route('/images/<filename>')
497
- # # # # # def uploaded_file(filename):
498
- # # # # # return send_from_directory(UPLOAD_FOLDER, filename)
499
-
500
- # # # # # @app.route('/')
501
- # # # # # def show_latest_image():
502
- # # # # # global latest_filename
503
- # # # # # if not latest_filename:
504
- # # # # # return "<h1>No image received yet</h1>"
505
-
506
- # # # # # # Auto-refresh the page every 3 seconds
507
- # # # # # html = '''
508
- # # # # # <html>
509
- # # # # # <head>
510
- # # # # # <meta http-equiv="refresh" content="3">
511
- # # # # # </head>
512
- # # # # # <body>
513
- # # # # # <h1>Latest Image</h1>
514
- # # # # # <img src="/images/{{ file }}" style="max-width:600px;"><br>
515
- # # # # # <small>{{ file }}</small>
516
- # # # # # </body>
517
- # # # # # </html>
518
- # # # # # '''
519
- # # # # # return render_template_string(html, file=latest_filename)
520
-
521
- # # # # # if __name__ == '__main__':
522
- # # # # # app.run(host='0.0.0.0', port=7860)
523
-
524
-
525
-
526
- # # # # ##########################################
527
-
528
- # # # # from flask import Flask, request, send_from_directory, render_template_string
529
- # # # # import os
530
- # # # # from datetime import datetime
531
- # # # # import cv2
532
- # # # # import torch
533
- # # # # from ultralytics import YOLO
534
- # # # # import base64
535
- # # # # import numpy as np
536
- # # # # import google.generativeai as genai
537
-
538
- # # # # # Initialize Flask app
539
- # # # # app = Flask(__name__)
540
-
541
- # # # # UPLOAD_FOLDER = '/tmp/received_images'
542
- # # # # os.makedirs(UPLOAD_FOLDER, exist_ok=True)
543
-
544
- # # # # latest_filename = None
545
- # # # # last_extraction_result = []
546
-
547
- # # # # # Set your Gemini API key
548
- # # # # genai.configure(api_key="AIzaSyD7aLN4NphvsPuyB6N3FwVw5Nxzv7gxzv4") # Replace for local or private space only
549
- # # # # gemma_model = genai.GenerativeModel(model_name="models/gemma-3-12b-it")
550
-
551
- # # # # def detect_and_extract_text(image_path, yolo_model_path):
552
- # # # # if not os.path.exists(image_path):
553
- # # # # print(f"Error: Image file not found at {image_path}")
554
- # # # # return []
555
-
556
- # # # # try:
557
- # # # # yolo = YOLO(yolo_model_path)
558
- # # # # except Exception as e:
559
- # # # # print(f"Error loading YOLO model: {e}")
560
- # # # # return []
561
-
562
- # # # # img = cv2.imread(image_path)
563
- # # # # if img is None:
564
- # # # # print(f"Error: Could not load image at {image_path}")
565
- # # # # return []
566
-
567
- # # # # try:
568
- # # # # results = yolo(image_path)
569
- # # # # except Exception as e:
570
- # # # # print(f"Error during YOLO inference: {e}")
571
- # # # # return []
572
-
573
- # # # # output = []
574
-
575
- # # # # for i, r in enumerate(results):
576
- # # # # for j, (box, cls) in enumerate(zip(r.boxes.xyxy, r.boxes.cls)):
577
- # # # # x1, y1, x2, y2 = map(int, box)
578
- # # # # cropped_img = img[y1:y2, x1:x2]
579
- # # # # class_name = yolo.names[int(cls)]
580
-
581
- # # # # try:
582
- # # # # cropped_img_rgb = cv2.cvtColor(cropped_img, cv2.COLOR_BGR2RGB)
583
- # # # # _, buffer = cv2.imencode('.jpg', cropped_img_rgb)
584
- # # # # image_data = base64.b64encode(buffer).decode('utf-8')
585
-
586
- # # # # response = gemma_model.generate_content([
587
- # # # # {
588
- # # # # "role": "user",
589
- # # # # "parts": [
590
- # # # # {"text": "Extract the text from this image."},
591
- # # # # {"inline_data": {"mime_type": "image/jpeg", "data": image_data}}
592
- # # # # ]
593
- # # # # }
594
- # # # # ])
595
- # # # # extracted_text = response.text.strip()
596
- # # # # if extracted_text.lower().startswith("the text in the image is"):
597
- # # # # extracted_text = extracted_text[len("The text in the image is"):].strip().strip('"').strip("'")
598
-
599
-
600
- # # # # output.append({
601
- # # # # "class_name": class_name,
602
- # # # # "extracted_text": extracted_text
603
- # # # # })
604
-
605
- # # # # except Exception as e:
606
- # # # # print(f"Error processing object {j+1} (Class={class_name}): {e}")
607
- # # # # output.append({
608
- # # # # "class_name": class_name,
609
- # # # # "extracted_text": "Error during text extraction",
610
- # # # # "bounding_box": [x1, y1, x2, y2]
611
- # # # # })
612
-
613
- # # # # return output
614
-
615
- # # # # @app.route('/upload', methods=['POST'])
616
- # # # # def upload_file():
617
- # # # # global latest_filename, last_extraction_result
618
- # # # # img_data = request.data
619
- # # # # filename = datetime.now().strftime("%Y%m%d_%H%M%S") + ".jpeg"
620
- # # # # filepath = os.path.join(UPLOAD_FOLDER, filename)
621
- # # # # with open(filepath, 'wb') as f:
622
- # # # # f.write(img_data)
623
- # # # # latest_filename = filename
624
-
625
- # # # # # Perform detection + text extraction
626
- # # # # try:
627
- # # # # last_extraction_result = detect_and_extract_text(filepath, "best.pt")
628
- # # # # except Exception as e:
629
- # # # # last_extraction_result = [{"class_name": "Error", "extracted_text": str(e), "bounding_box": []}]
630
-
631
- # # # # return 'OK', 200
632
-
633
- # # # # @app.route('/images/<filename>')
634
- # # # # def uploaded_file(filename):
635
- # # # # return send_from_directory(UPLOAD_FOLDER, filename)
636
-
637
- # # # # @app.route('/')
638
- # # # # def show_latest_image():
639
- # # # # global latest_filename, last_extraction_result
640
- # # # # if not latest_filename:
641
- # # # # return "<h1>No image received yet</h1>"
642
-
643
- # # # # html = '''
644
- # # # # <html>
645
- # # # # <head>
646
- # # # # <meta http-equiv="refresh" content="15">
647
- # # # # </head>
648
- # # # # <body>
649
- # # # # <h1>Latest Image</h1>
650
- # # # # <img src="/images/{{ file }}" style="max-width:600px;"><br>
651
- # # # # <small>{{ file }}</small>
652
-
653
- # # # # <h2>Extracted Information</h2>
654
- # # # # <ul>
655
- # # # # {% for item in result %}
656
- # # # # <li><b>{{ item.class_name }}</b>: {{ item.extracted_text }} [{{ item.bounding_box }}]</li>
657
- # # # # {% endfor %}
658
- # # # # </ul>
659
- # # # # </body>
660
- # # # # </html>
661
- # # # # '''
662
- # # # # return render_template_string(html, file=latest_filename, result=last_extraction_result)
663
-
664
- # # # # if __name__ == '__main__':
665
- # # # # app.run(host='0.0.0.0', port=7860)
666
-
667
-
668
- # # # ###########################################################################################################################################################################
669
-
670
-
671
-
672
-
673
-
674
-
675
- # # # from flask import Flask, request, send_from_directory, render_template_string, jsonify
676
- # # # import os
677
- # # # from datetime import datetime
678
- # # # import cv2
679
- # # # import torch
680
- # # # from ultralytics import YOLO
681
- # # # import base64
682
- # # # import numpy as np
683
- # # # import google.generativeai as genai
684
- # # # import json
685
-
686
- # # # # Initialize Flask app
687
- # # # app = Flask(__name__)
688
-
689
- # # # UPLOAD_FOLDER = '/tmp/received_images'
690
- # # # os.makedirs(UPLOAD_FOLDER, exist_ok=True)
691
-
692
- # # # latest_filename = None
693
- # # # last_extraction_result = []
694
-
695
- # # # # Set your Gemini API key
696
- # # # genai.configure(api_key="AIzaSyD7aLN4NphvsPuyB6N3FwVw5Nxzv7gxzv4")
697
- # # # gemma_model = genai.GenerativeModel(model_name="models/gemma-3-12b-it")
698
-
699
- # # # def prompt_engineered_extraction(base64_image):
700
- # # # try:
701
- # # # response = gemma_model.generate_content([
702
- # # # {
703
- # # # "role": "user",
704
- # # # "parts": [
705
- # # # {"text": "Extract only the exact text from this image. Return the result as a plain JSON array of strings like [\"value1\", \"value2\"]. Do not include any explanation, label, or formatting."},
706
- # # # {"inline_data": {"mime_type": "image/jpeg", "data": base64_image}}
707
- # # # ]
708
- # # # }
709
- # # # ])
710
- # # # extracted_text = response.text.strip()
711
-
712
- # # # # Try parsing JSON result
713
- # # # try:
714
- # # # values = json.loads(extracted_text)
715
- # # # if isinstance(values, list):
716
- # # # return ", ".join(values)
717
- # # # except json.JSONDecodeError:
718
- # # # # Fallback cleanup
719
- # # # cleaned = extracted_text.strip('[]').split(',')
720
- # # # cleaned = [v.strip().strip('"').strip("'") for v in cleaned]
721
- # # # return ", ".join(cleaned)
722
-
723
- # # # return extracted_text # Fallback raw
724
-
725
- # # # except Exception as e:
726
- # # # print("Error in prompt-engineered extraction:", e)
727
- # # # return "Error during text extraction"
728
-
729
- # # # def detect_and_extract_text(image_path, yolo_model_path):
730
- # # # if not os.path.exists(image_path):
731
- # # # print(f"Error: Image file not found at {image_path}")
732
- # # # return []
733
-
734
- # # # try:
735
- # # # yolo = YOLO(yolo_model_path)
736
- # # # except Exception as e:
737
- # # # print(f"Error loading YOLO model: {e}")
738
- # # # return []
739
-
740
- # # # img = cv2.imread(image_path)
741
- # # # if img is None:
742
- # # # print(f"Error: Could not load image at {image_path}")
743
- # # # return []
744
-
745
- # # # try:
746
- # # # results = yolo(image_path)
747
- # # # except Exception as e:
748
- # # # print(f"Error during YOLO inference: {e}")
749
- # # # return []
750
-
751
- # # # output = []
752
-
753
- # # # for i, r in enumerate(results):
754
- # # # for j, (box, cls) in enumerate(zip(r.boxes.xyxy, r.boxes.cls)):
755
- # # # x1, y1, x2, y2 = map(int, box)
756
- # # # cropped_img = img[y1:y2, x1:x2]
757
- # # # class_name = yolo.names[int(cls)]
758
-
759
- # # # try:
760
- # # # cropped_img_rgb = cv2.cvtColor(cropped_img, cv2.COLOR_BGR2RGB)
761
- # # # _, buffer = cv2.imencode('.jpg', cropped_img_rgb)
762
- # # # image_data = base64.b64encode(buffer).decode('utf-8')
763
-
764
- # # # extracted = prompt_engineered_extraction(image_data)
765
-
766
- # # # output.append({
767
- # # # "class_name": class_name,
768
- # # # "extracted_text": extracted,
769
- # # # "bounding_box": [x1, y1, x2, y2]
770
- # # # })
771
-
772
- # # # except Exception as e:
773
- # # # print(f"Error processing object {j+1} (Class={class_name}): {e}")
774
- # # # output.append({
775
- # # # "class_name": class_name,
776
- # # # "extracted_text": "Error during text extraction",
777
- # # # "bounding_box": [x1, y1, x2, y2]
778
- # # # })
779
-
780
- # # # return output
781
-
782
- # # # @app.route('/upload', methods=['POST'])
783
- # # # def upload_file():
784
- # # # global latest_filename, last_extraction_result
785
- # # # img_data = request.data
786
- # # # filename = datetime.now().strftime("%Y%m%d_%H%M%S") + ".jpeg"
787
- # # # filepath = os.path.join(UPLOAD_FOLDER, filename)
788
- # # # with open(filepath, 'wb') as f:
789
- # # # f.write(img_data)
790
- # # # latest_filename = filename
791
-
792
- # # # try:
793
- # # # last_extraction_result = detect_and_extract_text(filepath, "best.pt")
794
- # # # except Exception as e:
795
- # # # last_extraction_result = [{"class_name": "Error", "extracted_text": str(e), "bounding_box": []}]
796
-
797
- # # # return 'OK', 200
798
-
799
- # # # @app.route('/images/<filename>')
800
- # # # def uploaded_file(filename):
801
- # # # return send_from_directory(UPLOAD_FOLDER, filename)
802
-
803
- # # # @app.route('/latest')
804
- # # # def latest():
805
- # # # return jsonify({
806
- # # # "filename": latest_filename,
807
- # # # "result": last_extraction_result
808
- # # # })
809
-
810
- # # # @app.route('/')
811
- # # # def show_latest_image():
812
- # # # html = '''
813
- # # # <!DOCTYPE html>
814
- # # # <html>
815
- # # # <head>
816
- # # # <title>Live Image Monitor</title>
817
- # # # <script>
818
- # # # let lastFilename = "";
819
-
820
- # # # async function fetchLatest() {
821
- # # # try {
822
- # # # const response = await fetch("/latest");
823
- # # # const data = await response.json();
824
- # # # if (data.filename && data.filename !== lastFilename) {
825
- # # # document.getElementById("latest-img").src = "/images/" + data.filename + "?t=" + new Date().getTime();
826
- # # # document.getElementById("filename").innerText = data.filename;
827
-
828
- # # # let infoList = "";
829
- # # # for (const item of data.result) {
830
- # # # infoList += `<li><b>${item.class_name}</b>: ${item.extracted_text} [${item.bounding_box}]</li>`;
831
- # # # }
832
- # # # document.getElementById("info").innerHTML = infoList;
833
-
834
- # # # lastFilename = data.filename;
835
- # # # }
836
- # # # } catch (err) {
837
- # # # console.error("Error fetching latest data:", err);
838
- # # # }
839
- # # # }
840
-
841
- # # # setInterval(fetchLatest, 3000);
842
- # # # </script>
843
- # # # </head>
844
- # # # <body>
845
- # # # <h1>Latest Image</h1>
846
- # # # <img id="latest-img" src="" style="max-width:600px;"><br>
847
- # # # <small id="filename">Waiting for image...</small>
848
- # # # <h2>Extracted Information</h2>
849
- # # # <ul id="info"></ul>
850
- # # # </body>
851
- # # # </html>
852
- # # # '''
853
- # # # return render_template_string(html)
854
-
855
- # # # if __name__ == '__main__':
856
- # # # app.run(host='0.0.0.0', port=7860)
857
-
858
-
859
-
860
-
861
-
862
-
863
-
864
-
865
- # # ########################################################################################################
866
-
867
-
868
- # # from flask import Flask, request, send_from_directory, render_template_string, jsonify
869
- # # import os
870
- # # from datetime import datetime
871
- # # import cv2
872
- # # import torch
873
- # # from ultralytics import YOLO
874
- # # import base64
875
- # # import numpy as np
876
- # # import google.generativeai as genai
877
- # # import json
878
- # # import time
879
-
880
- # # # Initialize Flask app
881
- # # app = Flask(__name__)
882
-
883
- # # UPLOAD_FOLDER = '/tmp/received_images'
884
- # # os.makedirs(UPLOAD_FOLDER, exist_ok=True)
885
-
886
- # # latest_filename = None
887
- # # last_extraction_result = []
888
-
889
- # # # Set your Gemini API key
890
- # # genai.configure(api_key="AIzaSyD7aLN4NphvsPuyB6N3FwVw5Nxzv7gxzv4")
891
- # # gemma_model = genai.GenerativeModel(model_name="models/gemma-3-12b-it")
892
-
893
- # # def prompt_engineered_extraction(base64_image):
894
- # # try:
895
- # # response = gemma_model.generate_content([
896
- # # {
897
- # # "role": "user",
898
- # # "parts": [
899
- # # {"text": "Extract only the exact text from this image. Return the result as a plain JSON array of strings like [\"value1\", \"value2\"]. Do not include any explanation, label, or formatting."},
900
- # # {"inline_data": {"mime_type": "image/jpeg", "data": base64_image}}
901
- # # ]
902
- # # }
903
- # # ])
904
- # # extracted_text = response.text.strip()
905
-
906
- # # try:
907
- # # values = json.loads(extracted_text)
908
- # # if isinstance(values, list):
909
- # # return ", ".join(values)
910
- # # except json.JSONDecodeError:
911
- # # cleaned = extracted_text.strip('[]').split(',')
912
- # # cleaned = [v.strip().strip('"').strip("'") for v in cleaned]
913
- # # return ", ".join(cleaned)
914
-
915
- # # return extracted_text
916
-
917
- # # except Exception as e:
918
- # # print("Error in prompt-engineered extraction:", e)
919
- # # return "Error during text extraction"
920
-
921
- # # def detect_and_extract_text(image_path, yolo_model_path):
922
- # # if not os.path.exists(image_path):
923
- # # print(f"Error: Image file not found at {image_path}")
924
- # # return []
925
-
926
- # # try:
927
- # # yolo = YOLO(yolo_model_path)
928
- # # except Exception as e:
929
- # # print(f"Error loading YOLO model: {e}")
930
- # # return []
931
-
932
- # # img = cv2.imread(image_path)
933
- # # if img is None:
934
- # # print(f"Error: Could not load image at {image_path}")
935
- # # return []
936
-
937
- # # try:
938
- # # results = yolo(image_path)
939
- # # except Exception as e:
940
- # # print(f"Error during YOLO inference: {e}")
941
- # # return []
942
-
943
- # # output = []
944
-
945
- # # for i, r in enumerate(results):
946
- # # for j, (box, cls) in enumerate(zip(r.boxes.xyxy, r.boxes.cls)):
947
- # # x1, y1, x2, y2 = map(int, box)
948
- # # cropped_img = img[y1:y2, x1:x2]
949
- # # class_name = yolo.names[int(cls)]
950
-
951
- # # try:
952
- # # cropped_img_rgb = cv2.cvtColor(cropped_img, cv2.COLOR_BGR2RGB)
953
- # # _, buffer = cv2.imencode('.jpg', cropped_img_rgb)
954
- # # image_data = base64.b64encode(buffer).decode('utf-8')
955
-
956
- # # extracted = prompt_engineered_extraction(image_data)
957
-
958
- # # output.append({
959
- # # "class_name": class_name,
960
- # # "extracted_text": extracted,
961
- # # "bounding_box": [x1, y1, x2, y2]
962
- # # })
963
-
964
- # # except Exception as e:
965
- # # print(f"Error processing object {j+1} (Class={class_name}): {e}")
966
- # # output.append({
967
- # # "class_name": class_name,
968
- # # "extracted_text": "Error during text extraction",
969
- # # "bounding_box": [x1, y1, x2, y2]
970
- # # })
971
-
972
- # # return output
973
-
974
- # # @app.route('/upload', methods=['POST'])
975
- # # def upload_file():
976
- # # global latest_filename, last_extraction_result
977
- # # img_data = request.data
978
- # # filename = datetime.now().strftime("%Y%m%d_%H%M%S") + ".jpeg"
979
- # # filepath = os.path.join(UPLOAD_FOLDER, filename)
980
- # # with open(filepath, 'wb') as f:
981
- # # f.write(img_data)
982
- # # latest_filename = filename
983
- # # last_extraction_result = [] # Reset before processing
984
-
985
- # # try:
986
- # # last_extraction_result = detect_and_extract_text(filepath, "best.pt")
987
- # # except Exception as e:
988
- # # last_extraction_result = [{"class_name": "Error", "extracted_text": str(e), "bounding_box": []}]
989
-
990
- # # return 'OK', 200
991
-
992
- # # @app.route('/images/<filename>')
993
- # # def uploaded_file(filename):
994
- # # return send_from_directory(UPLOAD_FOLDER, filename)
995
-
996
- # # @app.route('/latest')
997
- # # def latest():
998
- # # global latest_filename, last_extraction_result
999
-
1000
- # # timeout = 10
1001
- # # start_time = time.time()
1002
-
1003
- # # # Wait for extraction result to be ready
1004
- # # while not last_extraction_result and (time.time() - start_time) < timeout:
1005
- # # time.sleep(0.5)
1006
-
1007
- # # return jsonify({
1008
- # # "filename": latest_filename,
1009
- # # "result": last_extraction_result
1010
- # # })
1011
-
1012
- # # @app.route('/')
1013
- # # def show_latest_image():
1014
- # # html = '''
1015
- # # <!DOCTYPE html>
1016
- # # <html>
1017
- # # <head>
1018
- # # <title>Live Image Monitor</title>
1019
- # # <script>
1020
- # # let lastFilename = "";
1021
-
1022
- # # async function fetchLatest() {
1023
- # # try {
1024
- # # const response = await fetch("/latest");
1025
- # # const data = await response.json();
1026
-
1027
- # # if (data.filename && data.filename !== lastFilename && data.result && data.result.length > 0) {
1028
- # # document.getElementById("latest-img").src = "/images/" + data.filename + "?t=" + new Date().getTime();
1029
- # # document.getElementById("filename").innerText = data.filename;
1030
-
1031
- # # let infoList = "";
1032
- # # for (const item of data.result) {
1033
- # # infoList += `<li><b>${item.class_name}</b>: ${item.extracted_text} [${item.bounding_box}]</li>`;
1034
- # # }
1035
- # # document.getElementById("info").innerHTML = infoList;
1036
-
1037
- # # lastFilename = data.filename;
1038
- # # }
1039
- # # } catch (err) {
1040
- # # console.error("Error fetching latest data:", err);
1041
- # # }
1042
- # # }
1043
-
1044
- # # setInterval(fetchLatest, 3000);
1045
- # # </script>
1046
- # # </head>
1047
- # # <body>
1048
- # # <h1>Latest Image</h1>
1049
- # # <img id="latest-img" src="" style="max-width:600px;"><br>
1050
- # # <small id="filename">Waiting for image...</small>
1051
- # # <h2>Extracted Information</h2>
1052
- # # <ul id="info"></ul>
1053
- # # </body>
1054
- # # </html>
1055
- # # '''
1056
- # # return render_template_string(html)
1057
-
1058
- # # if __name__ == '__main__':
1059
- # # app.run(host='0.0.0.0', port=7860)
1060
-
1061
-
1062
-
1063
-
1064
-
1065
-
1066
-
1067
-
1068
- # ###############################################################################################################
1069
-
1070
-
1071
-
1072
-
1073
-
1074
-
1075
- # from flask import Flask, request, send_from_directory, render_template_string, jsonify
1076
- # import os
1077
- # from datetime import datetime
1078
- # import cv2
1079
- # import torch
1080
- # from ultralytics import YOLO
1081
- # import base64
1082
- # import numpy as np
1083
- # import google.generativeai as genai
1084
- # import json
1085
- # import time
1086
- # import requests
1087
- # import pandas as pd
1088
-
1089
- # # Initialize Flask app
1090
- # app = Flask(__name__)
1091
-
1092
- # UPLOAD_FOLDER = '/tmp/received_images'
1093
- # os.makedirs(UPLOAD_FOLDER, exist_ok=True)
1094
-
1095
- # latest_filename = None
1096
- # last_extraction_result = []
1097
-
1098
- # # Set your Gemini API key
1099
- # genai.configure(api_key="AIzaSyD7aLN4NphvsPuyB6N3FwVw5Nxzv7gxzv4")
1100
- # gemma_model = genai.GenerativeModel(model_name="models/gemma-3-12b-it")
1101
-
1102
-
1103
- # def insert_to_supabase(values_dict):
1104
- # url = "https://vynkcgoqjotnhtshbrdf.supabase.co/rest/v1/vitals"
1105
- # headers = {
1106
- # "apikey": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZ5bmtjZ29xam90bmh0c2hicmRmIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTAxMzEwMzEsImV4cCI6MjA2NTcwNzAzMX0.TEC0I2WtCMcUTt6xo5RYIHUuiOcfsJLIiYdFuUVXZI4",
1107
- # "Authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZ5bmtjZ29xam90bmh0c2hicmRmIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTAxMzEwMzEsImV4cCI6MjA2NTcwNzAzMX0.TEC0I2WtCMcUTt6xo5RYIHUuiOcfsJLIiYdFuUVXZI4",
1108
- # "Content-Type": "application/json"
1109
- # }
1110
-
1111
- # try:
1112
- # response = requests.post(url, headers=headers, json=values_dict)
1113
- # if response.status_code == 201:
1114
- # print("✅ Successfully inserted to Supabase.")
1115
- # else:
1116
- # print("❌ Failed to insert to Supabase.")
1117
- # print("Status code:", response.status_code)
1118
- # print("Response:", response.text)
1119
- # except Exception as e:
1120
- # print("❌ Error sending data to Supabase:", e)
1121
-
1122
- # def prompt_engineered_extraction(base64_image):
1123
- # try:
1124
- # response = gemma_model.generate_content([
1125
- # {
1126
- # "role": "user",
1127
- # "parts": [
1128
- # {"text": "Extract only the exact text from this image. Return the result as a plain JSON array of strings like [\"value1\", \"value2\"]. Do not include any explanation, label, or formatting."},
1129
- # {"inline_data": {"mime_type": "image/jpeg", "data": base64_image}}
1130
- # ]
1131
- # }
1132
- # ])
1133
- # extracted_text = response.text.strip()
1134
-
1135
- # try:
1136
- # values = json.loads(extracted_text)
1137
- # if isinstance(values, list):
1138
- # return ", ".join(values)
1139
- # except json.JSONDecodeError:
1140
- # cleaned = extracted_text.strip('[]').split(',')
1141
- # cleaned = [v.strip().strip('"').strip("'") for v in cleaned]
1142
- # return ", ".join(cleaned)
1143
-
1144
- # return extracted_text
1145
-
1146
- # except Exception as e:
1147
- # print("Error in prompt-engineered extraction:", e)
1148
- # return "Error during text extraction"
1149
-
1150
- # def detect_and_extract_text(image_path, yolo_model_path):
1151
- # if not os.path.exists(image_path):
1152
- # print(f"❌ Error: Image file not found at {image_path}")
1153
- # return []
1154
-
1155
- # try:
1156
- # yolo = YOLO(yolo_model_path)
1157
- # except Exception as e:
1158
- # print(f"❌ Error loading YOLO model: {e}")
1159
- # return []
1160
-
1161
- # img = cv2.imread(image_path)
1162
- # if img is None:
1163
- # print(f"❌ Error: Could not load image at {image_path}")
1164
- # return []
1165
-
1166
- # try:
1167
- # results = yolo(image_path)
1168
- # except Exception as e:
1169
- # print(f"❌ Error during YOLO inference: {e}")
1170
- # return []
1171
-
1172
- # output = []
1173
- # vitals_dict = {} # To collect values for Supabase
1174
-
1175
- # for i, r in enumerate(results):
1176
- # for j, (box, cls) in enumerate(zip(r.boxes.xyxy, r.boxes.cls)):
1177
- # x1, y1, x2, y2 = map(int, box)
1178
- # cropped_img = img[y1:y2, x1:x2]
1179
- # class_name = yolo.names[int(cls)].lower()
1180
-
1181
- # try:
1182
- # cropped_img_rgb = cv2.cvtColor(cropped_img, cv2.COLOR_BGR2RGB)
1183
- # _, buffer = cv2.imencode('.jpg', cropped_img_rgb)
1184
- # image_data = base64.b64encode(buffer).decode('utf-8')
1185
-
1186
- # extracted = prompt_engineered_extraction(image_data)
1187
-
1188
- # # Parse and store valid vitals
1189
- # try:
1190
- # if class_name == "heart rate":
1191
- # vitals_dict["heart_rate"] = int(extracted)
1192
- # elif class_name == "respiratory rate":
1193
- # vitals_dict["respiratory_rate"] = int(extracted)
1194
- # elif class_name == "oxygen saturation":
1195
- # vitals_dict["oxygen_saturation"] = int(extracted)
1196
- # elif class_name == "blood pressure":
1197
- # if "/" in extracted:
1198
- # vitals_dict["blood_pressure"] = extracted # keep as string
1199
- # except Exception as ve:
1200
- # print(f"⚠️ Could not parse {class_name}: {extracted} — {ve}")
1201
-
1202
- # output.append({
1203
- # "class_name": class_name,
1204
- # "extracted_text": extracted,
1205
- # "bounding_box": [x1, y1, x2, y2]
1206
- # })
1207
-
1208
- # except Exception as e:
1209
- # print(f"❌ Error processing object {j+1} (Class={class_name}): {e}")
1210
- # output.append({
1211
- # "class_name": class_name,
1212
- # "extracted_text": "Error during text extraction",
1213
- # "bounding_box": [x1, y1, x2, y2]
1214
- # })
1215
-
1216
- # # ✅ Insert to Supabase if we have at least 1 valid value
1217
- # if vitals_dict:
1218
- # insert_to_supabase(vitals_dict)
1219
-
1220
- # return output
1221
-
1222
- # @app.route('/dashboard')
1223
- # def dashboard():
1224
- # html = '''
1225
- # <!DOCTYPE html>
1226
- # <html>
1227
- # <head>
1228
- # <title>Vitals Dashboard</title>
1229
- # <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
1230
- # </head>
1231
- # <body>
1232
- # <h1>Vitals Dashboard</h1>
1233
- # <div id="chart" style="width:100%;height:600px;"></div>
1234
- # <script>
1235
- # async function loadData() {
1236
- # const res = await fetch("/vitals_data");
1237
- # const data = await res.json();
1238
-
1239
- # if (data.error) {
1240
- # document.getElementById("chart").innerText = "Error: " + data.details;
1241
- # return;
1242
- # }
1243
-
1244
- # const timestamps = [];
1245
- # const heartRate = [];
1246
- # const respiratoryRate = [];
1247
- # const oxygen = [];
1248
- # const systolicBP = [];
1249
- # const diastolicBP = [];
1250
-
1251
- # for (const item of data) {
1252
- # timestamps.push(item.timestamp);
1253
- # heartRate.push(item.heart_rate);
1254
- # respiratoryRate.push(item.respiratory_rate);
1255
- # oxygen.push(item.oxygen_saturation);
1256
-
1257
- # if (item.blood_pressure && item.blood_pressure.includes('/')) {
1258
- # const [sys, dia] = item.blood_pressure.split('/');
1259
- # systolicBP.push(parseInt(sys));
1260
- # diastolicBP.push(parseInt(dia));
1261
- # } else {
1262
- # systolicBP.push(null);
1263
- # diastolicBP.push(null);
1264
- # }
1265
- # }
1266
-
1267
- # const layout = {
1268
- # title: "Vitals over Time",
1269
- # xaxis: { title: "Timestamp" },
1270
- # yaxis: { title: "Values" }
1271
- # };
1272
-
1273
- # const traces = [
1274
- # {
1275
- # x: timestamps,
1276
- # y: heartRate,
1277
- # name: "Heart Rate",
1278
- # type: "scatter"
1279
- # },
1280
- # {
1281
- # x: timestamps,
1282
- # y: respiratoryRate,
1283
- # name: "Respiratory Rate",
1284
- # type: "scatter"
1285
- # },
1286
- # {
1287
- # x: timestamps,
1288
- # y: oxygen,
1289
- # name: "Oxygen Saturation",
1290
- # type: "scatter"
1291
- # },
1292
- # {
1293
- # x: timestamps,
1294
- # y: systolicBP,
1295
- # name: "Systolic BP",
1296
- # type: "scatter"
1297
- # },
1298
- # {
1299
- # x: timestamps,
1300
- # y: diastolicBP,
1301
- # name: "Diastolic BP",
1302
- # type: "scatter"
1303
- # }
1304
- # ];
1305
-
1306
- # Plotly.newPlot("chart", traces, layout);
1307
- # }
1308
-
1309
- # loadData();
1310
- # </script>
1311
- # </body>
1312
- # </html>
1313
- # '''
1314
- # return render_template_string(html)
1315
-
1316
-
1317
-
1318
- # @app.route('/vitals_data')
1319
- # def vitals_data():
1320
- # supabase_url = "https://vynkcgoqjotnhtshbrdf.supabase.co/rest/v1/vitals"
1321
- # api_key = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZ5bmtjZ29xam90bmh0c2hicmRmIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTAxMzEwMzEsImV4cCI6MjA2NTcwNzAzMX0.TEC0I2WtCMcUTt6xo5RYIHUuiOcfsJLIiYdFuUVXZI4" # replace with your actual key
1322
-
1323
- # headers = {
1324
- # "apikey": api_key,
1325
- # "Authorization": f"Bearer {api_key}"
1326
- # }
1327
-
1328
- # response = requests.get(supabase_url, headers=headers)
1329
- # if response.status_code == 200:
1330
- # return jsonify(response.json())
1331
- # else:
1332
- # return jsonify({"error": "Failed to fetch data", "details": response.text}), 500
1333
-
1334
-
1335
-
1336
- # @app.route('/upload', methods=['POST'])
1337
- # def upload_file():
1338
- # global latest_filename, last_extraction_result
1339
- # img_data = request.data
1340
- # filename = datetime.now().strftime("%Y%m%d_%H%M%S") + ".jpeg"
1341
- # filepath = os.path.join(UPLOAD_FOLDER, filename)
1342
- # with open(filepath, 'wb') as f:
1343
- # f.write(img_data)
1344
- # latest_filename = filename
1345
- # last_extraction_result = [] # Reset before processing
1346
-
1347
- # try:
1348
- # last_extraction_result = detect_and_extract_text(filepath, "best.pt")
1349
- # except Exception as e:
1350
- # last_extraction_result = [{"class_name": "Error", "extracted_text": str(e), "bounding_box": []}]
1351
-
1352
- # return 'OK', 200
1353
-
1354
- # @app.route('/images/<filename>')
1355
- # def uploaded_file(filename):
1356
- # return send_from_directory(UPLOAD_FOLDER, filename)
1357
-
1358
- # @app.route('/latest')
1359
- # def latest():
1360
- # global latest_filename, last_extraction_result
1361
-
1362
- # timeout = 10
1363
- # start_time = time.time()
1364
-
1365
- # # Wait for extraction result to be ready
1366
- # while not last_extraction_result and (time.time() - start_time) < timeout:
1367
- # time.sleep(0.5)
1368
-
1369
- # return jsonify({
1370
- # "filename": latest_filename,
1371
- # "result": last_extraction_result
1372
- # })
1373
-
1374
- # @app.route('/')
1375
- # def show_latest_image():
1376
- # html = '''
1377
- # <!DOCTYPE html>
1378
- # <html>
1379
- # <head>
1380
- # <title>Live Image Monitor</title>
1381
- # <script>
1382
- # let lastFilename = "";
1383
- # async function fetchLatest() {
1384
- # try {
1385
- # const response = await fetch("/latest");
1386
- # const data = await response.json();
1387
- # if (data.filename && data.filename !== lastFilename && data.result && data.result.length > 0) {
1388
- # document.getElementById("latest-img").src = "/images/" + data.filename + "?t=" + new Date().getTime();
1389
- # document.getElementById("filename").innerText = data.filename;
1390
- # let infoList = "";
1391
- # for (const item of data.result) {
1392
- # infoList += `<li><b>${item.class_name}</b>: ${item.extracted_text} [${item.bounding_box}]</li>`;
1393
- # }
1394
- # document.getElementById("info").innerHTML = infoList;
1395
- # lastFilename = data.filename;
1396
- # }
1397
- # } catch (err) {
1398
- # console.error("Error fetching latest data:", err);
1399
- # }
1400
- # }
1401
- # setInterval(fetchLatest, 3000);
1402
- # </script>
1403
- # </head>
1404
- # <body>
1405
- # <h1>Latest Image</h1>
1406
- # <img id="latest-img" src="" style="max-width:600px;"><br>
1407
- # <small id="filename">Waiting for image...</small>
1408
- # <h2>Extracted Information</h2>
1409
- # <ul id="info"></ul>
1410
- # </body>
1411
- # </html>
1412
- # '''
1413
- # return render_template_string(html)
1414
-
1415
- # if __name__ == '__main__':
1416
- # app.run(host='0.0.0.0', port=7860)
1417
-
1418
-
1419
-
1420
-
1421
- ######################################################################################################################
 
166
  response = requests.get(url, headers=headers, params=params)
167
  return jsonify(response.json()) if response.status_code == 200 else jsonify({"error": response.text}), 500
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
 
170
  @app.route('/dashboard')
171
  def dashboard():
 
314
 
315
 
316
  if __name__ == '__main__':
317
+ app.run(host='0.0.0.0', port=7860)