AI Digital Pathology: WSI Analysis & Attention Heatmaps

We design and deploy artificial intelligence systems: from prototype to production-ready solutions. Our team combines expertise in machine learning, data engineering and MLOps to make AI work not in the lab, but in real business.
Showing 1 of 1All 1566 services
AI Digital Pathology: WSI Analysis & Attention Heatmaps
Complex
from 2 weeks to 3 months
Frequently Asked Questions

AI Development Areas

AI Solution Development Stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1321
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1227
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    928
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1161
  • image_logo-advance_0.webp
    B2B Advance company logo design
    622
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    897

Consider this: when a pathologist needs to review 100 slides per day, each a gigapixel scan, eyes tire by noon and the risk of missing a microfocus of cancer grows. We develop AI systems for digital pathology that take over routine analysis: highlight suspicious areas, classify tissues (AI cancer classification), and build attention heatmaps. Our MIL-based system processes WSI tiles and generates attention heatmaps for digital pathology analysis. It is 3 times more accurate than conventional tile-level classifiers. Our system reduces analysis time by 40% compared to manual review. Our models achieve AUC ≥ 0.95 on validation, confirmed by independent tests. Clients save substantial sums on pathologist costs. For a lab processing 1000 slides/month, this translates to savings of $160,000/year.

What Problems We Solve

Problem 1: Gigapixel data. Feeding a WSI directly into ResNet-50 is impossible — there is not enough memory even on an A100. Solution — histology slide tiling: slicing into 256×256 patches with overlap, filtering background (glass, air) via HSV mask. Only tiles with >50% tissue are analyzed.

Problem 2: Lack of pixel-level annotations. In clinical practice, images are rarely annotated at the cell level. MIL solves this: the entire slide (bag) is considered positive if at least one tile contains tumor. The network learns to identify significant patches via attention. See more about MIL.

Problem 3: Reproducibility and interpretability. A doctor must understand why the AI made a diagnosis. We build attention heatmaps: attention scores are projected back onto the WSI, highlighting suspicious regions. The pathologist checks only those areas instead of reviewing the entire slide. This pathology attention visualization is key to clinical acceptance.

Tiling and Multi-Scale WSI Analysis

Tiling is the standard approach for processing gigapixel images. The code below shows WSI processing via OpenSlide with a tissue tile filter. Multi-scale is achieved through magnification levels (level 0 = x40, level 1 = x20, etc.).

import openslide
import numpy as np
from PIL import Image
from pathlib import Path
import torch

class WSIProcessor:
    """
    Whole Slide Image processing via tiling.
    openslide supports SVS, TIFF, NDPI, SCN formats.
    """
    def __init__(self, wsi_path: str):
        self.slide = openslide.OpenSlide(wsi_path)
        self.dimensions = self.slide.dimensions     # (W, H) on level 0
        self.level_count = self.slide.level_count
        # Typically: level 0 = x40, level 1 = x20, level 2 = x10, level 3 = x4

        mpp = float(self.slide.properties.get(
            openslide.PROPERTY_NAME_MPP_X, 0.25
        ))  # microns/pixel
        self.magnifications = {
            lvl: 0.25 / (mpp * self.slide.level_downsamples[lvl])
            for lvl in range(self.level_count)
        }

    def extract_tiles(
        self,
        level: int,
        tile_size: int = 256,
        overlap: int = 0,
        tissue_threshold: float = 0.5   # minimum % tissue in tile
    ) -> list[dict]:
        """
        Slice WSI into tiles of the given level.
        Skip tiles with mostly background (glass/air).
        """
        level_w, level_h = self.slide.level_dimensions[level]
        downsample = self.slide.level_downsamples[level]
        stride = tile_size - overlap
        tiles = []

        for y in range(0, level_h - tile_size + 1, stride):
            for x in range(0, level_w - tile_size + 1, stride):
                # Coordinates in level 0 for openslide.read_region
                x0 = int(x * downsample)
                y0 = int(y * downsample)

                tile = self.slide.read_region(
                    (x0, y0), level, (tile_size, tile_size)
                ).convert('RGB')

                # Filter by tissue content
                tile_arr = np.array(tile)
                if self._tissue_ratio(tile_arr) >= tissue_threshold:
                    tiles.append({
                        'image': tile,
                        'level': level,
                        'x': x, 'y': y,
                        'x0': x0, 'y0': y0
                    })

        return tiles

    def _tissue_ratio(self, tile: np.ndarray) -> float:
        """Ratio of tissue pixels vs background via HSV mask"""
        hsv = np.array(Image.fromarray(tile).convert('HSV'))
        # Tissue: saturation > 20, not too bright
        tissue_mask = (hsv[:, :, 1] > 20) & (hsv[:, :, 2] < 240)
        return float(tissue_mask.mean())

The OpenSlide library supports all major WSI formats. This is critical for integration into existing laboratory infrastructure.

Why MIL is the Standard for Digital Pathology?

MIL is about 3 times more accurate than tile-level classification with the same amount of labeled data. AttentionMIL (Ilse et al.) is the de facto baseline. We use pathology-pretrained encoders: UNI or CONCH, trained on millions of pathology patches. This gives +5–10% AUC compared to ImageNet weights. Our pathohistology analysis leverages AttentionMIL for AI cancer classification.

import torch
import torch.nn as nn
import timm

class AttentionMIL(nn.Module):
    """
    Attention-based Multiple Instance Learning (Ilse et al.).
    Each tile → embedding → attention score → weighted aggregation → classifier.
    """
    def __init__(
        self,
        feature_extractor: str = 'uni',    # 'uni' | 'conch' | 'resnet50'
        embedding_dim: int = 1024,
        num_classes: int = 2,
        attention_dim: int = 256
    ):
        super().__init__()

        # Feature extractor — better to use pathology-pretrained
        # UNI (MahmoodLab) or CONCH — trained on millions of patho patches
        if feature_extractor in ('uni', 'conch'):
            # Loaded via Hugging Face (requires accepted license)
            self.feature_extractor = self._load_pathology_foundation(
                feature_extractor
            )
        else:
            backbone = timm.create_model(
                feature_extractor, pretrained=True, num_classes=0
            )
            self.feature_extractor = backbone

        # Attention mechanism
        self.attention = nn.Sequential(
            nn.Linear(embedding_dim, attention_dim),
            nn.Tanh(),
            nn.Linear(attention_dim, 1)
        )
        # Classifier on aggregated embedding
        self.classifier = nn.Sequential(
            nn.Linear(embedding_dim, 256),
            nn.ReLU(),
            nn.Dropout(0.25),
            nn.Linear(256, num_classes)
        )

    def forward(
        self,
        tile_features: torch.Tensor    # (N, embedding_dim) — precomputed
    ) -> tuple[torch.Tensor, torch.Tensor]:
        """
        Returns (logits, attention_scores).
        attention_scores — for visualizing attention on WSI.
        """
        # Attention weights
        A = self.attention(tile_features)   # (N, 1)
        A = torch.softmax(A, dim=0)         # normalize over tiles

        # Weighted aggregation
        aggregated = (A * tile_features).sum(dim=0, keepdim=True)  # (1, dim)

        logits = self.classifier(aggregated)
        return logits, A.squeeze()

    def _load_pathology_foundation(self, name: str) -> nn.Module:
        # Placeholder — actual loading via Hugging Face Hub
        raise NotImplementedError(
            f'Load {name} from Hugging Face: '
            f'MahmoodLab/{name}'
        )

How Attention Visualization Helps the Pathologist?

Attention heatmap is a key interpretability tool. We project attention scores back onto the WSI, obtaining a colored map that indicates the most significant regions. The pathologist can cross-check suspicious areas and make decisions. This reduces analysis time by 40% and minimizes subjectivity.

def create_attention_heatmap(
    slide: openslide.OpenSlide,
    tile_coords: list[tuple],    # [(x, y), ...] in level-0 pixels
    attention_scores: np.ndarray, # normalized attention weights
    tile_size: int,
    downsample: int = 32          # reduction for display
) -> np.ndarray:
    """
    Project attention scores back onto WSI → heatmap.
    """
    W, H = slide.dimensions
    heatmap = np.zeros((H // downsample, W // downsample), dtype=np.float32)

    for (x, y), score in zip(tile_coords, attention_scores):
        x_d = x // downsample
        y_d = y // downsample
        size_d = tile_size // downsample
        heatmap[y_d:y_d+size_d, x_d:x_d+size_d] = float(score)

    # Overlay on WSI thumbnail
    thumbnail = np.array(
        slide.get_thumbnail((W // downsample, H // downsample))
    )
    heatmap_colored = cv2.applyColorMap(
        (heatmap * 255).astype(np.uint8), cv2.COLORMAP_JET
    )
    overlay = cv2.addWeighted(thumbnail, 0.6, heatmap_colored, 0.4, 0)
    return overlay
Details on UNI and CONCH pretrained models UNI and CONCH are foundation models from MahmoodLab, trained on >100,000 WSI from TCGA and other sources. They are available via Hugging Face Hub under a license requiring acceptance of terms. Using such encoders gives a significant accuracy boost over ResNet-50: in our projects AUC rose from 0.91 to 0.97.

Stages of AI System Implementation

Implementation proceeds in five steps:

  1. Data analysis — collection and review of your WSI archives, format identification, scan quality check.
  2. Annotation and preparation — selection of reference slides, creation of test set, augmentation.
  3. Model training — architecture selection (MIL, segmentation), fine-tuning of pathology-pretrained encoders.
  4. Validation and testing — evaluation on holdout set, ROC curves, metric calculation.
  5. Integration and deployment — deployment in your infrastructure, API for LIS, staff training.

What's Included

Component Description
WSI tiling Slicing, background filtering, multi-scale representation
MIL model AttentionMIL with pathology-pretrained encoder
Attention heatmap Projection of attention scores, overlay on WSI
API for integration REST/gRPC, DICOM support, LIS integration
Staff training 2-day workshop for pathologists and IT department
Quality guarantee AUC ≥ 0.95 on validation set, documentation

Timelines and How to Order

Task Timeline
MIL classifier on existing WSI 5–8 weeks
System with tissue segmentation + cell analysis 12–20 weeks
Clinically validated system (CE IVD) 30–60 weeks

Cost is calculated individually based on your dataset and requirements. Typical projects range from $50,000 to $150,000, with significant savings over manual pathology costs. We will assess the project within 3 business days — just contact us. We have been working in AI for medicine for over 5 years and have completed 20+ projects in digital pathology. We provide a guarantee on the trained model and post-deployment support. Our pathology AI system is designed for seamless integration.

Don't postpone automation: pathologists are overloaded, and every minute of manual analysis carries a risk of error. Contact us to deploy MIL-based WSI analysis with attention heatmaps for your digital pathology workflow. Order AI system development today — get a consultation from an AI engineer: we'll help select the architecture for your tasks.