snowflakes16/CV_Course_Project
0
1import streamlit as st2import cv23import numpy as np4import os5import torch6import time7from PIL import Image8import matplotlib.pyplot as plt9from matplotlib.figure import Figure10import io11from ultralytics import YOLO12 13# Set page configuration with an improved layout14st.set_page_config(15 page_title="Brain Tumor Detection",16 page_icon="🧠",17 layout="wide",18 initial_sidebar_state="expanded"19)20 21# Custom CSS for better styling22st.markdown("""23<style>24 .main-header {25 font-size: 2.5rem;26 color: #1E3A8A;27 text-align: center;28 margin-bottom: 1rem;29 font-weight: 700;30 }31 .sub-header {32 font-size: 1.5rem;33 color: #1E3A8A;34 margin-top: 1rem;35 margin-bottom: 0.5rem;36 font-weight: 600;37 }38 .method-card {39 background-color: #f8f9fa;40 padding: 20px;41 border-radius: 10px;42 box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);43 margin-bottom: 20px;44 }45 .info-box {46 background-color: #e8f4ff;47 padding: 15px;48 border-radius: 8px;49 border-left: 5px solid #4361ee;50 margin: 10px 0;51 }52 .results-container {53 background-color: #f0f0f0;54 padding: 15px;55 border-radius: 10px;56 margin-top: 20px;57 }58 .stProgress > div > div {59 background-color: #4361ee;60 }61 .footer {62 text-align: center;63 color: #666;64 padding: 20px 0;65 font-size: 0.8rem;66 }67</style>68""", unsafe_allow_html=True)69 70# Constants71HEIGHT = 25672WIDTH = 25673 74# Custom function to display images similar to ShowImage in original code75def show_image_grid(images, titles, cmaps):76 """77 Create a figure with multiple subplots for image display.78 Similar to the ShowImage function in the original code.79 """80 fig = Figure(figsize=(15, 4))81 axs = fig.subplots(1, len(images))82 83 for i, (img, title, cmap) in enumerate(zip(images, titles, cmaps)):84 axs[i].imshow(img, cmap=cmap)85 axs[i].set_title(title)86 axs[i].axis('off')87 88 fig.tight_layout()89 return fig90 91def watershed_segmentation(image):92 """93 Apply watershed segmentation to an image.94 95 Args:96 image (np.ndarray): The input image in BGR format.97 98 Returns:99 fig (matplotlib.figure.Figure): Matplotlib figure with visualized steps.100 brain_out (np.ndarray): Final segmented color image.101 mask (np.ndarray): Binary tumor mask.102 """103 # Convert to grayscale104 grey_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)105 106 # Apply thresholding to obtain a binary image107 _, threshold = cv2.threshold(grey_img, 0, 255, cv2.THRESH_OTSU)108 _, labeled_image = cv2.connectedComponents(threshold)109 110 # Find the largest component (presumed to be the brain)111 marker_area = [np.sum(labeled_image == m) for m in range(1, np.max(labeled_image))]112 largest_component = np.argmax(marker_area) + 1113 foreground = labeled_image == largest_component114 brain_out = image.copy()115 brain_out[foreground == False] = (0, 0, 0)116 117 color_image=image118 grey_img = cv2.cvtColor(color_image, cv2.COLOR_BGR2GRAY)119 computed_threshold, threshold = cv2.threshold(grey_img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)120 kernel = np.ones((3, 3), np.uint8)121 opening = cv2.morphologyEx(threshold, cv2.MORPH_OPEN, kernel, iterations=2)122 background = cv2.dilate(opening, kernel, iterations=3)123 dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)124 computed_threshold, transform_threshold = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0)125 transform_threshold = np.uint8(transform_threshold)126 unknown = cv2.subtract(background, transform_threshold)127 computed_threshold, labeled_image = cv2.connectedComponents(transform_threshold)128 labeled_image = labeled_image + 1129 labeled_image[unknown == 255] = 0130 131 labeled_image = cv2.watershed(color_image, labeled_image)132 color_image[labeled_image == -1] = [255, 0, 0]133 im1 = cv2.cvtColor(color_image, cv2.COLOR_HSV2RGB)134 135 # Apply morphological closing to refine the brain mask136 foreground = np.uint8(foreground)137 kernel = np.ones((8, 8), np.uint8)138 closing = cv2.morphologyEx(foreground, cv2.MORPH_CLOSE, kernel)139 140 141 # Apply morphological operations to refine the segmentation142 # _, threshold_inv = cv2.threshold(grey_img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)143 # kernel = np.ones((3, 3), np.uint8)144 # opening = cv2.morphologyEx(threshold_inv, cv2.MORPH_OPEN, kernel, iterations=2)145 # background = cv2.dilate(opening, kernel, iterations=3)146 # dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)147 # _, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0)148 149 # sure_fg = np.uint8(sure_fg)150 # unknown = cv2.subtract(background, sure_fg)151 152 # _, markers = cv2.connectedComponents(sure_fg)153 # markers = markers + 1154 # markers[unknown == 255] = 0155 156 # # Apply watershed157 # watershed_img = image.copy()158 # markers = cv2.watershed(watershed_img, markers)159 # watershed_img[markers == -1] = [255, 0, 0] # boundaries in red160 161 # # Final mask from closing operation162 # brain_mask = np.uint8(foreground)163 # kernel = np.ones((8, 8), np.uint8)164 # closing = cv2.morphologyEx(brain_mask, cv2.MORPH_CLOSE, kernel)165 166 # Masked output image167 brain_out = image.copy()168 brain_out[closing == 0] = (0, 0, 0)169 170 # Create figure with steps171 fig, axs = plt.subplots(1, 4, figsize=(20, 5))172 axs[0].imshow(cv2.cvtColor(grey_img, cv2.COLOR_GRAY2RGB))173 axs[0].set_title("Grayscale Image")174 axs[1].imshow(threshold, cmap='gray')175 axs[1].set_title("Initial Thresholding")176 axs[2].imshow(im1, cmap='gray')177 axs[2].set_title("Watershed Output")178 axs[3].imshow(closing, cmap='gray')179 axs[3].set_title("Final Mask")180 for ax in axs:181 ax.axis("off")182 plt.tight_layout()183 184 return fig, brain_out, closing185 186# Load YOLO model at startup187@st.cache_resource188def load_yolo_model():189 try:190 # Check if we have a custom model available191 if os.path.exists("best_1.pt"):192 return YOLO("best_1.pt")193 # Try loading pretrained model194 elif os.path.exists("yolov8s.pt"):195 return YOLO("yolov8s.pt")196 else:197 # Download a small model if needed198 return YOLO("yolov8n.pt")199 except Exception as e:200 st.error(f"Error loading YOLO model: {e}")201 return None202 203# Function to get image for processing204def get_image_for_processing():205 if uploaded_file is not None:206 # Process uploaded file207 file_bytes = np.asarray(bytearray(uploaded_file.read()), dtype=np.uint8)208 return cv2.imdecode(file_bytes, cv2.IMREAD_COLOR), "Uploaded MRI Scan"209 elif use_sample:210 # Use sample image211 sample_images = ["2.png", "992.png"]212 if os.path.exists(sample_images[sample_index]):213 return cv2.imread(sample_images[sample_index]), f"Sample Image {sample_index+1}"214 else:215 # Create a sample image if none exists216 img = np.ones((HEIGHT, WIDTH, 3), dtype=np.uint8) * 200217 cv2.putText(img, f"Sample {sample_index+1}", (50, HEIGHT//2), 218 cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2)219 return img, f"Generated Sample {sample_index+1}"220 return None, ""221 222# Sidebar with improved styling223with st.sidebar:224 st.image("https://img.icons8.com/fluency/96/000000/brain.png", width=80)225 st.markdown("<h2 style='text-align: center; color: #1E3A8A;'>Brain Tumor Detection</h2>", unsafe_allow_html=True)226 st.markdown("<p style='text-align: center;'>Upload an MRI scan to detect brain tumors using advanced techniques.</p>", unsafe_allow_html=True)227 228 st.markdown("---")229 230 # Model selection with better formatting231 st.markdown("### Detection Method")232 detection_method = st.selectbox(233 "Choose a technique",234 ["Watershed Segmentation", "YOLOv8 Detection"],235 index=0,236 help="Select which algorithm to use for tumor detection"237 )238 239 st.markdown("### Input Image")240 # File uploader with better description241 uploaded_file = st.file_uploader("Upload MRI Scan", 242 type=["png", "jpg", "jpeg"],243 help="Upload a brain MRI image for analysis")244 245 # Add sample images option with better UI246 use_sample = st.checkbox("Use sample image instead", 247 help="Use a pre-loaded sample MRI scan")248 249 if use_sample:250 sample_index = st.slider("Select sample image", 0, 1, 0,251 help="Choose from available sample images")252 253 st.markdown("---")254 255 # Add brief method description based on selection256 if detection_method == "Watershed Segmentation":257 st.markdown("""258 <div class='info-box'>259 <b>Watershed Segmentation</b> is a classical computer vision technique that treats the image as a topographical surface, finding boundaries between regions.260 </div>261 """, unsafe_allow_html=True)262 else:263 st.markdown("""264 <div class='info-box'>265 <b>YOLOv8 Detection</b> is a deep learning approach that can identify and locate brain tumors in a single pass with high accuracy.266 </div>267 """, unsafe_allow_html=True)268 269# Main content with improved layout270st.markdown("<h1 class='main-header'>🧠 Brain Tumor Detection</h1>", unsafe_allow_html=True)271 272import base64273 274 275# Progress bar to show app is loading276progress_bar = st.progress(0)277for i in range(100):278 time.sleep(0.005) # Small delay for visual effect279 progress_bar.progress(i + 1)280progress_bar.empty() # Remove progress bar after loading281 282# Get image283image, image_caption = get_image_for_processing()284 285if image is not None:286 # Create columns for better layout287 col1, col2 = st.columns([1, 1])288 289 with col1:290 # Display original image with better styling291 st.markdown("<h3 class='sub-header'>Input MRI Scan</h3>", unsafe_allow_html=True)292 image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)293 st.image(image_rgb, caption=image_caption, use_container_width=True)294 295 with col2:296 # Method info297 st.markdown("<h3 class='sub-header'>Selected Method</h3>", unsafe_allow_html=True)298 if detection_method == "Watershed Segmentation":299 st.markdown("""300 <div class='method-card'>301 <h4>Watershed Segmentation</h4>302 <p>A classical computer vision technique that segments the image by treating it as a topographical surface.</p>303 <ol>304 <li><b>Thresholding:</b> Converts image to binary using Otsu's method</li>305 <li><b>Component Analysis:</b> Identifies the brain region</li>306 <li><b>Distance Transform:</b> Calculates distances to boundaries</li>307 <li><b>Watershed Algorithm:</b> Finds region boundaries</li>308 <li><b>Morphological Operations:</b> Refines the segmentation</li>309 </ol>310 </div>311 """, unsafe_allow_html=True)312 else:313 st.markdown("""314 <div class='method-card'>315 <h4>YOLOv8 Detection</h4>316 <p>A state-of-the-art deep learning approach for object detection.</p>317 <ul>318 <li><b>Single Pass:</b> Processes the entire image at once</li>319 <li><b>Region Prediction:</b> Identifies tumor regions</li>320 <li><b>Confidence Scores:</b> Provides detection reliability</li>321 <li><b>Multiple Classes:</b> Can detect various tumor types</li>322 </ul>323 </div>324 """, unsafe_allow_html=True)325 326 # Add a divider for visual separation327 st.markdown("<hr style='margin: 30px 0; border-top: 1px solid #ddd;'>", unsafe_allow_html=True)328 st.markdown("<h2 style='text-align: center; color: #1E3A8A;'>Analysis Results</h2>", unsafe_allow_html=True)329 330 # Process based on selected method331 if detection_method == "Watershed Segmentation":332 with st.spinner("Performing watershed segmentation..."):333 # Show a progress indicator for better UX334 progress_placeholder = st.empty()335 for i in range(100):336 # Update progress bar to simulate processing337 progress_placeholder.progress(i + 1)338 time.sleep(0.01) # Small delay for visual effect339 340 start_time = time.time()341 fig, brain_out, mask = watershed_segmentation(image)342 end_time = time.time()343 344 # Remove progress bar after completion345 progress_placeholder.empty()346 347 # Display processing time in a nicer way348 st.markdown(f"""349 <div style='background-color: #e8f4ff; padding: 10px; border-radius: 5px; text-align: center;'>350 <span style='font-size: 1.2rem;'>⏱️ Processing time: <b>{end_time - start_time:.2f} seconds</b></span>351 </div>352 """, unsafe_allow_html=True)353 354 # Display results355 st.pyplot(fig)356 357 # # Display the segmented brain in a nicer layout358 # st.markdown("<h3 class='sub-header'>Segmentation Output</h3>", unsafe_allow_html=True)359 # col1, col2 = st.columns(2)360 # with col1:361 # st.markdown("<p style='text-align: center;'><b>Extracted Brain Tissue</b></p>", unsafe_allow_html=True)362 # st.image(cv2.cvtColor(brain_out, cv2.COLOR_BGR2RGB), use_column_width=True)363 # with col2:364 # st.markdown("<p style='text-align: center;'><b>Tumor Mask</b></p>", unsafe_allow_html=True)365 # st.image(mask*255, use_column_width=True)366 367 # Add conclusion section368 st.markdown("""369 <div class='results-container'>370 <h4 style='text-align: center; margin-bottom: 15px;'>Analysis Conclusion</h4>371 <p>The watershed segmentation has successfully identified regions of interest in the MRI scan. 372 The extracted brain tissue shows the isolated brain region, while the tumor mask highlights 373 potential tumor regions based on intensity differences.</p>374 <p>For clinical use, these results should be verified by a medical professional.</p>375 </div>376 """, unsafe_allow_html=True)377 378 elif detection_method == "YOLOv8 Detection":379 # Load model - will use cached version after first load380 yolo_model = load_yolo_model()381 382 if yolo_model is not None:383 with st.spinner("Running YOLOv8 detection..."):384 progress_placeholder = st.empty()385 for i in range(100):386 progress_placeholder.progress(i + 1)387 time.sleep(0.01)388 389 temp_path = "temp_image.jpg"390 cv2.imwrite(temp_path, image)391 392 start_time = time.time()393 results = yolo_model(temp_path)394 end_time = time.time()395 396 progress_placeholder.empty()397 398 st.markdown(f"""399 <div style='background-color: #e8f4ff; padding: 10px; border-radius: 5px; text-align: center;'>400 <span style='font-size: 1.2rem;'>⏱️ Processing time: <b>{end_time - start_time:.2f} seconds</b></span>401 </div>402 """, unsafe_allow_html=True)403 404 # Center-aligned image with reduced width405 result_img = results[0].plot()406 st.markdown("<h3 class='sub-header'>Detection Result</h3>", unsafe_allow_html=True)407 st.markdown(408 f"<div style='text-align: center;'><img src='data:image/jpeg;base64,{base64.b64encode(cv2.imencode('.jpg', result_img)[1]).decode()}' style='max-width: 80%; height: auto; border-radius: 10px;'/></div>",409 unsafe_allow_html=True410 )411 412 try:413 boxes = results[0].boxes414 if boxes is not None and len(boxes) > 0:415 # st.markdown("<h3 class='sub-header'>Detection Details</h3>", unsafe_allow_html=True)416 417 # table_html = """418 # <div style='overflow-x: auto;'>419 # <table style='width: 100%; border-collapse: collapse; margin: 20px 0;'>420 # <thead>421 # <tr style='background-color: #1E3A8A; color: white;'>422 # <th style='padding: 12px; text-align: left;'>ID</th>423 # <th style='padding: 12px; text-align: left;'>Object</th>424 # <th style='padding: 12px; text-align: left;'>Confidence</th>425 # <th style='padding: 12px; text-align: left;'>Coordinates</th>426 # </tr>427 # </thead>428 # <tbody>429 # """430 431 # for i, box in enumerate(boxes):432 # conf = float(box.conf[0]) if hasattr(box, 'conf') else 0.0433 # cls = int(box.cls[0]) if hasattr(box, 'cls') else -1434 # coords = box.xyxy[0].cpu().numpy().astype(int) if hasattr(box, 'xyxy') else [0, 0, 0, 0]435 # cls_name = results[0].names[cls] if hasattr(results[0], 'names') and cls in results[0].names else f"Class {cls}"436 437 # bg_color = "#f2f2f2" if i % 2 == 0 else "white"438 # conf_color = "#388e3c" if conf > 0.7 else "#f57c00" if conf > 0.5 else "#d32f2f"439 440 # table_html += f"""441 # <tr style='background-color: {bg_color};'>442 # <td style='padding: 10px;'>{i + 1}</td>443 # <td style='padding: 10px;'><b>{cls_name}</b></td>444 # <td style='padding: 10px; color: {conf_color};'><b>{conf:.2f}</b></td>445 # <td style='padding: 10px;'>[{coords[0]}, {coords[1]}, {coords[2]}, {coords[3]}]</td>446 # </tr>447 # """448 449 # table_html += """450 # </tbody>451 # </table>452 # </div>453 # """454 455 # st.markdown(table_html, unsafe_allow_html=True)456 457 st.markdown("""458 <div class='results-container'>459 <h4 style='text-align: center; margin-bottom: 15px;'>Analysis Conclusion</h4>460 <p>The YOLOv8 model has successfully detected potential tumor regions in the MRI scan with the associated confidence scores.</p>461 <p>Higher confidence scores (>0.7) indicate greater detection reliability. For clinical use, these results should be verified by a medical professional.</p>462 </div>463 """, unsafe_allow_html=True)464 # else:465 # # st.markdown("""466 # # <div style='background-color: #e8f4ff; padding: 15px; border-radius: 8px; text-align: center; margin: 20px 0;'>467 # # <span style='font-size: 1.1rem;'>ℹ️ No tumors were detected in this image.</span>468 # # </div>469 # # """, unsafe_allow_html=True)470 # a=1471 except Exception as e:472 st.warning(f"Could not process detection details: {e}")473 474 if os.path.exists(temp_path):475 os.remove(temp_path)476 477 # elif detection_method == "YOLOv8 Detection":478 # # Load model - will use cached version after first load479 # yolo_model = load_yolo_model()480 481 # if yolo_model is not None:482 # with st.spinner("Running YOLOv8 detection..."):483 # # Show a progress indicator for better UX484 # progress_placeholder = st.empty()485 # for i in range(100):486 # # Update progress bar to simulate processing487 # progress_placeholder.progress(i + 1)488 # time.sleep(0.01) # Small delay for visual effect489 490 # # Save image to temporary file491 # temp_path = "temp_image.jpg"492 # cv2.imwrite(temp_path, image)493 494 # # Run detection495 # start_time = time.time()496 # results = yolo_model(temp_path)497 # end_time = time.time()498 499 # # Remove progress bar after completion500 # progress_placeholder.empty()501 502 # # Display processing time in a nicer way503 # st.markdown(f"""504 # <div style='background-color: #e8f4ff; padding: 10px; border-radius: 5px; text-align: center;'>505 # <span style='font-size: 1.2rem;'>⏱️ Processing time: <b>{end_time - start_time:.2f} seconds</b></span>506 # </div>507 # """, unsafe_allow_html=True)508 509 # # Get the result image with bounding boxes510 # result_img = results[0].plot()511 512 # # Display result with better styling513 # st.markdown("<h3 class='sub-header'>Detection Result</h3>", unsafe_allow_html=True)514 # # st.image(result_img, use_container_width=True)515 # st.image(result_img, caption="YOLOv8 Detection Output", width=600)516 517 518 # # Display detection info if available519 # try:520 # boxes = results[0].boxes521 # if len(boxes) > 0:522 # st.markdown("<h3 class='sub-header'>Detection Details</h3>", unsafe_allow_html=True)523 524 # # Create a better-looking table to display detections525 # table_html = """526 # <div style='overflow-x: auto;'>527 # <table style='width: 100%; border-collapse: collapse; margin: 20px 0;'>528 # <thead>529 # <tr style='background-color: #1E3A8A; color: white;'>530 # <th style='padding: 12px; text-align: left;'>ID</th>531 # <th style='padding: 12px; text-align: left;'>Object</th>532 # <th style='padding: 12px; text-align: left;'>Confidence</th>533 # <th style='padding: 12px; text-align: left;'>Coordinates</th>534 # </tr>535 # </thead>536 # <tbody>537 # """538 539 # for i, box in enumerate(boxes):540 # conf = box.conf.item()541 # cls = int(box.cls.item())542 # cls_name = results[0].names[cls] if cls in results[0].names else f"Class {cls}"543 # coords = box.xyxy.cpu().numpy()[0]544 545 # bg_color = "#f2f2f2" if i % 2 == 0 else "white"546 # conf_color = "#388e3c" if conf > 0.7 else "#f57c00" if conf > 0.5 else "#d32f2f"547 548 # table_html += f"""549 # <tr style='background-color: {bg_color};'>550 # <td style='padding: 10px;'>{i+1}</td>551 # <td style='padding: 10px;'><b>{cls_name}</b></td>552 # <td style='padding: 10px; color: {conf_color};'><b>{conf:.2f}</b></td>553 # <td style='padding: 10px;'>[{int(coords[0])}, {int(coords[1])}, {int(coords[2])}, {int(coords[3])}]</td>554 # </tr>555 # """556 557 # table_html += """558 # </tbody>559 # </table>560 # </div>561 # """562 563 # st.markdown(table_html, unsafe_allow_html=True)564 565 # # Add conclusion based on detections566 # st.markdown("""567 # <div class='results-container'>568 # <h4 style='text-align: center; margin-bottom: 15px;'>Analysis Conclusion</h4>569 # <p>The YOLOv8 model has successfully detected potential tumor regions in the MRI scan with the associated confidence scores.</p>570 # <p>Higher confidence scores (>0.7) indicate greater detection reliability. For clinical use, these results should be verified by a medical professional.</p>571 # </div>572 # """, unsafe_allow_html=True)573 # else:574 # st.markdown("""575 # <div style='background-color: #e8f4ff; padding: 15px; border-radius: 8px; text-align: center; margin: 20px 0;'>576 # <span style='font-size: 1.1rem;'>ℹ️ No tumors were detected in this image.</span>577 # </div>578 # """, unsafe_allow_html=True)579 # except Exception as e:580 # st.warning(f"Could not process detection details: {e}")581 582 # Cleanup temporary file583 if os.path.exists(temp_path):584 os.remove(temp_path)585 else:586 st.error("YOLO model could not be loaded. Please check the logs for details.")587 588else:589 # Display instructions when no file is uploaded - with better styling590 st.markdown("""591 <div style='background-color: #f8f9fa; padding: 30px; border-radius: 10px; text-align: center; margin: 20px 0;'>592 <img src="https://img.icons8.com/color/96/000000/upload-to-cloud.png" width="60">593 <h2 style='margin-top: 20px; color: #1E3A8A;'>Get Started</h2>594 <p style='font-size: 1.1rem; margin: 20px 0;'>Upload an MRI scan or select a sample image to begin analysis</p>595 </div>596 """, unsafe_allow_html=True)597 598 # Create method cards for better explanation599 col1, col2 = st.columns(2)600 601 with col1:602 st.markdown("""603 <div class='method-card'>604 <h3 style='color: #1E3A8A; text-align: center;'>Watershed Segmentation</h3>605 <p>A classical computer vision approach that treats the image as a topographical map and finds "watershed lines" that separate different regions.</p>606 <p><b>Best for:</b> Clearly defined boundaries, high contrast MRI scans</p>607 <div style='text-align: center;'>608 <img src="https://img.icons8.com/color/96/000000/watershed.png" width="50">609 </div>610 </div>611 """, unsafe_allow_html=True)612 613 with col2:614 st.markdown("""615 <div class='method-card'>616 <h3 style='color: #1E3A8A; text-align: center;'>YOLOv8 Detection</h3>617 <p>Modern deep learning object detection approach that can identify and locate brain tumors in a single pass.</p>618 <p><b>Best for:</b> Complex scans, subtle tumor detection, multiple tumor identification</p>619 <div style='text-align: center;'>620 <img src="https://img.icons8.com/color/96/000000/artificial-intelligence.png" width="50">621 </div>622 </div>623 """, unsafe_allow_html=True)624 625# Add information about the project with better styling626with st.expander("ℹ️ About this project"):627 st.markdown("""628 <div style='padding: 15px 0;'>629 <h3 style='color: #1E3A8A;'>Brain Tumor Detection Project</h3>630 <p>This application demonstrates brain tumor detection using multiple computer vision and deep learning approaches.</p>631 632 <h4>Technologies Used:</h4>633 <ul>634 <li><b>Computer Vision:</b> OpenCV, Watershed algorithm</li>635 <li><b>Deep Learning:</b> YOLOv8 object detection</li>636 <li><b>Web Framework:</b> Streamlit</li>637 </ul>638 639 <p>The watershed algorithm is particularly useful for medical image segmentation as it can identify boundaries between different tissues based on intensity gradients.</p>640 641 <h4>Important Note:</h4>642 <p>This application is for educational and demonstration purposes only. It is not intended for clinical use or medical diagnosis. Always consult with qualified healthcare professionals for medical advice and diagnosis.</p>643 </div>644 """, unsafe_allow_html=True)645 646# Footer with better styling647st.markdown("""648<div class='footer'>649 <hr>650 <p>Brain Tumor Detection Project | Created using Streamlit</p>651 <p>© 2025 | For research and educational purposes only</p>652</div>653""", unsafe_allow_html=True)