Anonymous-AC commited on
Commit
291bc98
Β·
verified Β·
1 Parent(s): 5bd459b

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +70 -400
app.py CHANGED
@@ -1,399 +1,3 @@
1
- # # import os
2
- # # import shutil
3
-
4
- # # # Clean and recreate HF cache directory
5
- # # cache_dir = "/tmp/hf_cache"
6
- # # if os.path.exists(cache_dir):
7
- # # shutil.rmtree(cache_dir)
8
- # # os.makedirs(cache_dir, exist_ok=True)
9
- # # os.environ["HF_HOME"] = cache_dir
10
-
11
- # import streamlit as st
12
- # from PIL import Image
13
- # import torch
14
- # from transformers import AutoModelForCausalLM, AutoProcessor
15
- # import numpy as np
16
- # import supervision as sv
17
- # import albumentations as A
18
- # import cv2
19
- # from transformers import AutoConfig
20
- # import yaml
21
-
22
- # # Set Streamlit page configuration for a wide layout
23
- # st.set_page_config(layout="wide")
24
-
25
- # # Custom CSS for better layout and mobile responsiveness
26
- # st.markdown("""
27
- # <style>
28
- # .main {
29
- # max-width: 1200px; /* Max width for content */
30
- # margin: 0 auto;
31
- # }
32
- # .block-container {
33
- # padding-top: 2rem;
34
- # padding-bottom: 2rem;
35
- # padding-left: 3rem;
36
- # padding-right: 3rem;
37
- # }
38
- # .title {
39
- # font-size: 3.2rem;
40
- # text-align: center;
41
- # background: linear-gradient(135deg, #0575e6 0%, #ff0080 50%, #7928ca 100%);
42
- # -webkit-background-clip: text;
43
- # -webkit-text-fill-color: transparent;
44
- # background-clip: text;
45
- # }
46
-
47
- # @keyframes gradientShift {
48
- # 0% { background-position: 0% 50%; }
49
- # 50% { background-position: 100% 50%; }
50
- # 100% { background-position: 0% 50%; }
51
- # }
52
- # .subheader {
53
- # font-size: 1.5rem;
54
- # margin-bottom: 20px;
55
- # }
56
- # .btn {
57
- # font-size: 1.1rem;
58
- # padding: 10px 20px;
59
- # background-color: #FF6347;
60
- # color: white;
61
- # border-radius: 5px;
62
- # border: none;
63
- # cursor: pointer;
64
- # }
65
- # .btn:hover {
66
- # background-color: #FF4500;
67
- # }
68
- # .column-spacing {
69
- # display: flex;
70
- # justify-content: space-between;
71
- # }
72
- # .col-half {
73
- # width: 48%;
74
- # }
75
- # .col-full {
76
- # width: 100%;
77
- # }
78
- # .instructions {
79
- # padding: 20px;
80
- # background-color: #f9f9f9;
81
- # border-radius: 8px;
82
- # box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
83
- # }
84
- # </style>
85
- # """, unsafe_allow_html=True)
86
-
87
- # # Load Model and Processor
88
- # @st.cache_resource
89
- # def load_model():
90
- # MODEL_NAME = 'Anonymous-AC/K2Sight-Lite'
91
- # DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
92
- # model = AutoModelForCausalLM.from_pretrained(MODEL_NAME, trust_remote_code=True).to(DEVICE)
93
- # processor = AutoProcessor.from_pretrained(MODEL_NAME, trust_remote_code=True)
94
- # processor.image_processor.size = 512
95
- # processor.image_processor.crop_size = 512
96
-
97
- # return model, processor, DEVICE
98
-
99
- # model, processor, DEVICE = load_model()
100
-
101
- # # Load Definitions
102
- # @st.cache_resource
103
- # def load_definitions():
104
- # vindr_path = 'configs/vindr_definition.yaml'
105
- # padchest_path = 'configs/padchest_definition.yaml'
106
- # prompt_path = 'examples/prompt.yaml'
107
-
108
- # with open(vindr_path, 'r') as file:
109
- # vindr_definitions = yaml.safe_load(file)
110
- # with open(padchest_path, 'r') as file:
111
- # padchest_definitions = yaml.safe_load(file)
112
- # with open(prompt_path, 'r') as file:
113
- # prompt_definitions = yaml.safe_load(file)
114
-
115
- # return vindr_definitions, padchest_definitions, prompt_definitions
116
-
117
- # vindr_definitions, padchest_definitions, prompt_definitions = load_definitions()
118
-
119
- # dataset_options = {"Vindr": vindr_definitions, "PadChest": padchest_definitions}
120
-
121
- # def load_example_images():
122
- # return list(prompt_definitions.keys())
123
-
124
- # example_images = load_example_images()
125
-
126
- # def apply_transform(image, size_mode=512):
127
- # pad_resize_transform = A.Compose([
128
- # A.LongestMaxSize(max_size=size_mode, interpolation=cv2.INTER_AREA),
129
- # A.PadIfNeeded(min_height=size_mode, min_width=size_mode, border_mode=cv2.BORDER_CONSTANT, value=(0, 0, 0)),
130
- # A.Resize(height=512, width=512, interpolation=cv2.INTER_AREA),
131
- # ])
132
- # image_np = np.array(image)
133
- # transformed = pad_resize_transform(image=image_np)
134
- # return transformed["image"]
135
-
136
- # # Streamlit UI with Colorful Title and Emojis
137
- # # st.markdown("<div style='text-align: center;'><span style='font-size: 3rem;'>🩺</span></div>", unsafe_allow_html=True)
138
- # st.markdown("<h1 class='title'>Knowledge to Sight: Reasoning over Visual Attributes via Knowledge Decomposition for Abnormality Grounding</h1>", unsafe_allow_html=True)
139
- # # st.markdown("<div style='text-align: center;'><span style='font-size: 3rem;'>πŸš€</span></div>", unsafe_allow_html=True)
140
- # st.markdown(
141
- # "<p style='text-align: center; font-size: 18px;'>Welcome to a simple demo of our work! πŸŽ‰ Choose an example or upload your own image to get started! πŸ‘‡</p>",
142
- # unsafe_allow_html=True
143
- # )
144
-
145
- # # Display Example Images First
146
- # st.subheader("πŸŒ„ Example Images")
147
- # selected_example = st.selectbox("Choose an example", example_images)
148
- # image = Image.open(selected_example).convert("RGB")
149
- # example_diseases = prompt_definitions.get(selected_example, [])
150
- # st.write("**Associated Diseases:**", ", ".join(example_diseases))
151
-
152
- # # Layout for Original Image and Instructions
153
- # col1, col2 = st.columns([1, 2])
154
-
155
- # # Left column for original image
156
- # with col1:
157
- # st.image(image, caption=f"Original Example Image: {selected_example}", width=400)
158
-
159
- # # Right column for Instructions and Run Inference Button
160
- # with col2:
161
- # st.subheader("βš™οΈ Instructions to Get Started:")
162
- # st.write("""
163
- # - **Run Inference**: Click the "Run Inference on Example" button to process the image and display the results.
164
- # - **Choose an Example**: πŸŒ„ Select an example image from the dataset to view its associated diseases.
165
- # - **Upload Your Own Image**: πŸ“€ Upload an image of your choice to analyze it for diseases.
166
- # - **Select Dataset**: πŸ“š Choose between available datasets (Vindr or PadChest) for disease information.
167
- # - **Select Disease**: 🦠 Pick the disease to be analyzed from the list of diseases in the selected dataset.
168
- # """)
169
-
170
- # st.subheader("⚠️ Warning:")
171
- # st.write("""
172
- # - **🚫 Please avoid uploading non-frontal chest X-ray images.** Our model has been specifically trained on **frontal chest X-ray images** only.
173
- # - This demo is intended for **πŸ”¬ research purposes only** and should **❌ not be used for medical diagnoses**.
174
- # - The model’s responses may contain **<span style='color:#dc3545; font-weight:bold;'>πŸ€– hallucinations or incorrect information</span>**.
175
- # - Always consult a **<span style='color:#dc3545; font-weight:bold;'>πŸ‘¨β€βš•οΈ medical professional</span>** for accurate diagnosis and advice.
176
- # """, unsafe_allow_html=True)
177
-
178
-
179
- # st.markdown("</div>", unsafe_allow_html=True)
180
-
181
- # # Run Inference Button
182
- # if st.button("Run Inference on Example", key="example"):
183
- # if image is None:
184
- # st.error("❌ Please select an example image first.")
185
- # else:
186
- # # Use the selected example's disease and definition for inference
187
- # disease_choice = example_diseases[0] if example_diseases else ""
188
- # definition = vindr_definitions.get(disease_choice, padchest_definitions.get(disease_choice, ""))
189
-
190
- # # Generate the prompt for the model
191
- # det_obj = f"{disease_choice} means {definition}."
192
- # st.write(f"**Definition:** {definition}")
193
- # prompt = f"Locate the phrases in the caption: {det_obj}."
194
- # prompt = f"<CAPTION_TO_PHRASE_GROUNDING>{prompt}"
195
-
196
- # # Prepare the image and input
197
- # np_image = np.array(image)
198
- # inputs = processor(text=[prompt], images=[np_image], return_tensors="pt", padding=True).to(DEVICE)
199
-
200
- # with st.spinner("Processing... ⏳"):
201
- # outputs = model.generate(
202
- # input_ids=inputs["input_ids"],
203
- # pixel_values=inputs["pixel_values"],
204
- # max_new_tokens=1024,
205
- # num_beams=3,
206
- # output_scores=True, # Make sure we get the scores/logits
207
- # return_dict_in_generate=True # Ensures you get both sequences and scores in the output
208
- # )
209
-
210
-
211
- # # Ensure transition_scores is properly extracted
212
- # transition_scores = model.compute_transition_scores(
213
- # outputs.sequences, outputs.scores, outputs.beam_indices, normalize_logits=False
214
- # )
215
-
216
- # # Get the generated token IDs (ignoring the input tokens part)
217
- # generated_ids = outputs.sequences
218
- # generated_text = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
219
-
220
- # # Get input length
221
- # input_length = inputs.input_ids.shape[1]
222
- # generated_tokens = outputs.sequences
223
-
224
- # # Calculate output length (number of generated tokens)
225
- # output_length = np.sum(transition_scores.cpu().numpy() < 0, axis=1)
226
-
227
- # # Get length penalty
228
- # length_penalty = model.generation_config.length_penalty
229
-
230
- # # Calculate total score for the generated sentence
231
- # reconstructed_scores = transition_scores.cpu().sum(axis=1) / (output_length**length_penalty)
232
-
233
- # # Convert log-probability to probability (0-1 range)
234
- # probabilities = np.exp(reconstructed_scores.cpu().numpy())
235
-
236
- # # Streamlit UI to display the result
237
- # st.markdown(f"**🎯 Probability of the Results:** <span style='color:#28a745; font-size:24px; font-weight:bold;'>{probabilities[0] * 100:.2f}%</span>", unsafe_allow_html=True)
238
-
239
-
240
- # predictions = processor.post_process_generation(generated_text, task="<CAPTION_TO_PHRASE_GROUNDING>", image_size=np_image.shape[:2])
241
-
242
- # detection = sv.Detections.from_lmm(sv.LMM.FLORENCE_2, predictions, resolution_wh=np_image.shape[:2])
243
-
244
- # # Annotate the image with bounding boxes and labels
245
- # bounding_box_annotator = sv.BoundingBoxAnnotator(color_lookup=sv.ColorLookup.INDEX)
246
- # label_annotator = sv.LabelAnnotator(color_lookup=sv.ColorLookup.INDEX)
247
- # image_with_predictions = bounding_box_annotator.annotate(np_image.copy(), detection)
248
- # image_with_predictions = label_annotator.annotate(image_with_predictions, detection)
249
- # annotated_image = Image.fromarray(image_with_predictions.astype(np.uint8))
250
-
251
- # # Display the original and result images side by side
252
- # col1, col2 = st.columns([1, 1])
253
-
254
- # with col1:
255
- # st.image(image, caption=f"Original Image: {selected_example}", width=400)
256
-
257
- # with col2:
258
- # st.image(annotated_image, caption="Inference Results πŸ–ΌοΈ", width=400)
259
-
260
- # # Display the generated text
261
- # st.write("**Generated Text:**", generated_text)
262
-
263
- # # Upload Image section
264
- # st.subheader("πŸ“€ Upload Your Own Image")
265
-
266
- # col1, col2 = st.columns([1, 1])
267
- # with col1:
268
- # dataset_choice = st.selectbox("Select Dataset πŸ“š", options=list(dataset_options.keys()))
269
- # disease_options = list(dataset_options[dataset_choice].keys())
270
- # with col2:
271
- # disease_choice = st.selectbox("Select Disease 🦠", options=disease_options)
272
-
273
- # uploaded_file = st.file_uploader("Upload an Image", type=["png", "jpg", "jpeg"])
274
-
275
-
276
- # col1, col2 = st.columns([1, 2])
277
-
278
- # with col1:
279
- # # Handle file upload
280
- # if uploaded_file:
281
- # image = Image.open(uploaded_file).convert("RGB")
282
- # image = apply_transform(image) # Ensure the uploaded image is transformed correctly
283
- # st.image(image, caption="Uploaded Image", width=400)
284
-
285
- # # Let user select dataset and disease dynamically
286
- # disease_choice = disease_choice if disease_choice else example_diseases[0]
287
-
288
- # # Get Definition Priority: Dataset -> User Input
289
- # definition = vindr_definitions.get(disease_choice, padchest_definitions.get(disease_choice, ""))
290
- # if not definition:
291
- # definition = st.text_input("Enter Definition Manually πŸ“", value="")
292
-
293
- # with col2:
294
- # # Instructions and warnings
295
- # st.subheader("βš™οΈ Instructions to Get Started:")
296
- # st.write("""
297
- # - **Run Inference**: Click the "Run Inference on Example" button to process the image and display the results.
298
- # - **Choose an Example**: πŸŒ„ Select an example image from the dataset to view its associated diseases.
299
- # - **Upload Your Own Image**: πŸ“€ Upload an image of your choice to analyze it for diseases.
300
- # - **Select Dataset**: πŸ“š Choose between available datasets (Vindr or PadChest) for disease information.
301
- # - **Select Disease**: 🦠 Pick the disease to be analyzed from the list of diseases in the selected dataset.
302
- # """)
303
-
304
- # st.subheader("⚠️ Warning:")
305
- # st.write("""
306
- # - **🚫 Please avoid uploading non-frontal chest X-ray images.** Our model has been specifically trained on **frontal chest X-ray images** only.
307
- # - This demo is intended for **πŸ”¬ research purposes only** and should **❌ not be used for medical diagnoses**.
308
- # - The model’s responses may contain **<span style='color:#dc3545; font-weight:bold;'>πŸ€– hallucinations or incorrect information</span>**.
309
- # - Always consult a **<span style='color:#dc3545; font-weight:bold;'>πŸ‘¨β€βš•οΈ medical professional</span>** for accurate diagnosis and advice.
310
- # """, unsafe_allow_html=True)
311
-
312
- # # Run inference after upload
313
- # if st.button("Run Inference πŸƒβ€β™‚οΈ"):
314
- # if image is None:
315
- # st.error("❌ Please upload an image or select an example.")
316
- # else:
317
- # det_obj = f"{disease_choice} means {definition}."
318
- # st.write(f"**Definition:** {definition}")
319
-
320
- # # Construct Prompt with Disease Definition
321
- # prompt = f"Locate the phrases in the caption: {det_obj}."
322
- # prompt = f"<CAPTION_TO_PHRASE_GROUNDING>{prompt}"
323
-
324
- # np_image = np.array(image)
325
- # inputs = processor(text=[prompt], images=[np_image], return_tensors="pt", padding=True).to(DEVICE)
326
-
327
- # with st.spinner("Processing... ⏳"):
328
- # # generated_ids = model.generate(input_ids=inputs["input_ids"], pixel_values=inputs["pixel_values"], max_new_tokens=1024, num_beams=3)
329
- # # generated_text = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
330
-
331
- # outputs = model.generate(
332
- # input_ids=inputs["input_ids"],
333
- # pixel_values=inputs["pixel_values"],
334
- # max_new_tokens=1024,
335
- # num_beams=3,
336
- # output_scores=True, # Make sure we get the scores/logits
337
- # return_dict_in_generate=True # Ensures you get both sequences and scores in the output
338
- # )
339
-
340
- # transition_scores = model.compute_transition_scores(
341
- # outputs.sequences, outputs.scores, outputs.beam_indices, normalize_logits=False
342
- # )
343
-
344
- # # Get the generated token IDs (ignoring the input tokens part)
345
- # generated_ids = outputs.sequences
346
- # generated_text = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
347
-
348
- # # Get input length
349
- # input_length = inputs.input_ids.shape[1]
350
-
351
- # # Extract generated tokens (ignoring the input tokens)
352
- # # generated_tokens = outputs.sequences[:, input_length:]
353
- # generated_tokens = outputs.sequences
354
-
355
- # # Calculate output length (number of generated tokens)
356
- # output_length = np.sum(transition_scores.cpu().numpy() < 0, axis=1)
357
-
358
- # # Get length penalty
359
- # length_penalty = model.generation_config.length_penalty
360
-
361
- # # Calculate total score for the generated sentence
362
- # reconstructed_scores = transition_scores.cpu().sum(axis=1) / (output_length**length_penalty)
363
-
364
- # # Convert log-probability to probability (0-1 range)
365
- # probabilities = np.exp(reconstructed_scores.cpu().numpy())
366
-
367
- # # Streamlit UI to display the result
368
-
369
- # # st.write(f"**Probability of the Results (0-1):** {probabilities[0]:.4f}")
370
- # st.markdown(f"**🎯 Probability of the Results:** <span style='color:green; font-size:24px; font-weight:bold;'>{probabilities[0] * 100:.2f}%</span>", unsafe_allow_html=True)
371
-
372
-
373
-
374
- # predictions = processor.post_process_generation(generated_text, task="<CAPTION_TO_PHRASE_GROUNDING>", image_size=np_image.shape[:2])
375
-
376
- # detection = sv.Detections.from_lmm(sv.LMM.FLORENCE_2, predictions, resolution_wh=np_image.shape[:2])
377
-
378
- # bounding_box_annotator = sv.BoundingBoxAnnotator(color_lookup=sv.ColorLookup.INDEX)
379
- # label_annotator = sv.LabelAnnotator(color_lookup=sv.ColorLookup.INDEX)
380
- # image_with_predictions = bounding_box_annotator.annotate(np_image.copy(), detection)
381
- # image_with_predictions = label_annotator.annotate(image_with_predictions, detection)
382
- # annotated_image = Image.fromarray(image_with_predictions.astype(np.uint8))
383
-
384
- # # Create two columns to display the original and the results side by side
385
- # col1, col2 = st.columns([1, 1])
386
-
387
- # # Left column for original image
388
- # with col1:
389
- # st.image(image, caption="Uploaded Image", width=400)
390
-
391
- # # Right column for result image
392
- # with col2:
393
- # st.image(annotated_image, caption="Inference Results πŸ–ΌοΈ", width=400)
394
-
395
- # # Display the generated text
396
- # st.write("**Generated Text:**", generated_text)
397
 
398
  import streamlit as st
399
  from PIL import Image
@@ -423,9 +27,18 @@ st.markdown("""
423
  padding-right: 3rem;
424
  }
425
  .title {
426
- font-size: 2.5rem;
427
  text-align: center;
428
- color: #FF6347;
 
 
 
 
 
 
 
 
 
429
  }
430
  .subheader {
431
  font-size: 1.5rem;
@@ -462,6 +75,59 @@ st.markdown("""
462
  </style>
463
  """, unsafe_allow_html=True)
464
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
465
  # Load Model and Processor
466
  @st.cache_resource
467
  def load_model():
@@ -520,7 +186,8 @@ def apply_transform(image, size_mode=512):
520
  return transformed["image"]
521
 
522
  # Streamlit UI with Colorful Title and Emojis
523
- st.markdown("<h1 class='title'>🩺 Knowledge to Sight: Reasoning over Visual Attributes via Knowledge Decomposition for Abnormality Grounding πŸš€</h1>", unsafe_allow_html=True)
 
524
  st.markdown(
525
  "<p style='text-align: center; font-size: 18px;'>Welcome to a simple demo of our work! πŸŽ‰ Choose an example or upload your own image to get started! πŸ‘‡</p>",
526
  unsafe_allow_html=True
@@ -692,7 +359,10 @@ with col2:
692
  - The model’s responses may contain **<span style='color:#dc3545; font-weight:bold;'>πŸ€– hallucinations or incorrect information</span>**.
693
  - Always consult a **<span style='color:#dc3545; font-weight:bold;'>πŸ‘¨β€βš•οΈ medical professional</span>** for accurate diagnosis and advice.
694
  """, unsafe_allow_html=True)
695
-
 
 
 
696
  # Run inference after upload
697
  if st.button("Run Inference πŸƒβ€β™‚οΈ"):
698
  if image is None:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
 
2
  import streamlit as st
3
  from PIL import Image
 
27
  padding-right: 3rem;
28
  }
29
  .title {
30
+ font-size: 3.2rem;
31
  text-align: center;
32
+ background: linear-gradient(135deg, #0575e6 0%, #ff0080 50%, #7928ca 100%);
33
+ -webkit-background-clip: text;
34
+ -webkit-text-fill-color: transparent;
35
+ background-clip: text;
36
+ }
37
+
38
+ @keyframes gradientShift {
39
+ 0% { background-position: 0% 50%; }
40
+ 50% { background-position: 100% 50%; }
41
+ 100% { background-position: 0% 50%; }
42
  }
43
  .subheader {
44
  font-size: 1.5rem;
 
75
  </style>
76
  """, unsafe_allow_html=True)
77
 
78
+ # # Custom CSS for better layout and mobile responsiveness
79
+ # st.markdown("""
80
+ # <style>
81
+ # .main {
82
+ # max-width: 1200px; /* Max width for content */
83
+ # margin: 0 auto;
84
+ # }
85
+ # .block-container {
86
+ # padding-top: 2rem;
87
+ # padding-bottom: 2rem;
88
+ # padding-left: 3rem;
89
+ # padding-right: 3rem;
90
+ # }
91
+ # .title {
92
+ # font-size: 2.5rem;
93
+ # text-align: center;
94
+ # color: #FF6347;
95
+ # }
96
+ # .subheader {
97
+ # font-size: 1.5rem;
98
+ # margin-bottom: 20px;
99
+ # }
100
+ # .btn {
101
+ # font-size: 1.1rem;
102
+ # padding: 10px 20px;
103
+ # background-color: #FF6347;
104
+ # color: white;
105
+ # border-radius: 5px;
106
+ # border: none;
107
+ # cursor: pointer;
108
+ # }
109
+ # .btn:hover {
110
+ # background-color: #FF4500;
111
+ # }
112
+ # .column-spacing {
113
+ # display: flex;
114
+ # justify-content: space-between;
115
+ # }
116
+ # .col-half {
117
+ # width: 48%;
118
+ # }
119
+ # .col-full {
120
+ # width: 100%;
121
+ # }
122
+ # .instructions {
123
+ # padding: 20px;
124
+ # background-color: #f9f9f9;
125
+ # border-radius: 8px;
126
+ # box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
127
+ # }
128
+ # </style>
129
+ # """, unsafe_allow_html=True)
130
+
131
  # Load Model and Processor
132
  @st.cache_resource
133
  def load_model():
 
186
  return transformed["image"]
187
 
188
  # Streamlit UI with Colorful Title and Emojis
189
+ # st.markdown("<h1 class='title'>🩺 Knowledge to Sight: Reasoning over Visual Attributes via Knowledge Decomposition for Abnormality Grounding πŸš€</h1>", unsafe_allow_html=True)
190
+ st.markdown("<h1 class='title'>Knowledge to Sight: Reasoning over Visual Attributes via Knowledge Decomposition for Abnormality Grounding </h1>", unsafe_allow_html=True)
191
  st.markdown(
192
  "<p style='text-align: center; font-size: 18px;'>Welcome to a simple demo of our work! πŸŽ‰ Choose an example or upload your own image to get started! πŸ‘‡</p>",
193
  unsafe_allow_html=True
 
359
  - The model’s responses may contain **<span style='color:#dc3545; font-weight:bold;'>πŸ€– hallucinations or incorrect information</span>**.
360
  - Always consult a **<span style='color:#dc3545; font-weight:bold;'>πŸ‘¨β€βš•οΈ medical professional</span>** for accurate diagnosis and advice.
361
  """, unsafe_allow_html=True)
362
+ st.markdown("""
363
+ <img src="//www.clustrmaps.com/map_v2.png?d=uM9v_RTadJ3hLvNbBSQ2PZ0KNPABbilkZgDyiXmuC0M&cl=ffffff"
364
+ style="position:absolute;top:-9999px;left:-9999px;width:1px;height:1px;visibility:hidden;opacity:0;pointer-events:none;z-index:-1;display:none;" />
365
+ """, unsafe_allow_html=True)
366
  # Run inference after upload
367
  if st.button("Run Inference πŸƒβ€β™‚οΈ"):
368
  if image is None: