CoolFace
Apppublic

snowflakes16/CV_Course_Project

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
app.py653 linesDownload Raw Back to root
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)