AI for CT Analysis: Segmentation, Detection, Quantitative Analysis

Manual analysis of CT scans with hundreds of slices is time-consuming and labor-intensive, increasing the risk of missing important details. We develop AI systems that automate organ segmentation, nodule detection, and quantitative analysis, relieving radiologists of routine workload. Our team delivers turnkey projects—from data collection to integration into clinical practice—providing a reliable solution that scales with your business.

AI Development Areas

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1344
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1307
  • B2B Advance company logo design
    B2B Advance company logo design
    754
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1050
  • AIDER company logo development
    AIDER company logo development
    994
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1097

A radiologist spends 20–40 minutes analyzing a single CT study with hundreds of slices. With a load of 30 studies per day, fatigue accumulates and small nodules on slices get missed. We develop AI systems that take over routine tasks: organ segmentation, nodule detection, volume measurement. Our experience: 10+ years in medical CV, 30+ deployed projects. The result — a 50% reduction in analysis time and significant cost savings for the clinic. We offer a turnkey solution from data collection to PACS integration.

Why AI for CT Is Harder than for X-Ray

Computed tomography produces three-dimensional data: a stack of 200–600 slices with thickness 0.5–5 mm. The key feature is Hounsfield units (HU), a quantitative measure of tissue density. AI must work in 3D, account for voxel anisotropy and HU ranges that differ by task (lungs: -1200..600 HU, soft tissues: -150..250 HU). Additionally, scanner and protocol variability require robust preprocessing.

How We Solve 3D Segmentation Problems

Stack: PyTorch, MONAI, nnU-Net. For preprocessing we use MONAI transforms — NIfTI loading, RAS orientation reorientation, resampling to isotropic spacing (1.5×1.5×2.0 mm), windowing by HU. The base architecture is a 3D U-Net with residual blocks.

import numpy as np
import torch
import nibabel as nib
from monai.transforms import (
    Compose,
    LoadImaged,
    AddChanneld,
    Orientationd,
    Spacingd,
    ScaleIntensityRanged,
    CropForegroundd,
    ResizeWithPadOrCropd,
    ToTensord
)

class CTAnalysisSystem:
    def __init__(self, model_path: str, task: str = 'lung_nodule'):
        self.preprocessing = self._build_preprocessing(task)
        self.model = self._load_model(model_path)
        self.task = task

    def _build_preprocessing(self, task: str) -> Compose:
        if task == 'lung_nodule':
            hu_min, hu_max = -1200, 600
        elif task == 'liver_tumor':
            hu_min, hu_max = -150, 250
        else:
            hu_min, hu_max = -1000, 1000

        return Compose([
            LoadImaged(keys=['image']),
            AddChanneld(keys=['image']),
            Orientationd(keys=['image'], axcodes='RAS'),
            Spacingd(keys=['image'], pixdim=(1.5, 1.5, 2.0), mode='bilinear'),
            ScaleIntensityRanged(
                keys=['image'],
                a_min=hu_min,
                a_max=hu_max,
                b_min=0.0,
                b_max=1.0,
                clip=True
            ),
            ToTensord(keys=['image'])
        ])

    def analyze(self, nifti_path: str) -> dict:
        data = {'image': nifti_path}
        data = self.preprocessing(data)
        volume = data['image'].unsqueeze(0)
        with torch.no_grad():
            prediction = self.model(volume)
        if self.task == 'lung_nodule':
            return self._process_nodule_detection(prediction, data)
        elif self.task == 'organ_segmentation':
            return self._process_segmentation(prediction)

MONAI and nnU-Net: Industry Standard

MONAI is a framework for medical CV from NVIDIA and King's College. nnU-Net is a self-configuring method: it automatically determines the optimal architecture and preprocessing for each dataset. Using MONAI reduces preprocessing code by a factor of 2 and increases Dice by 5% compared to manual implementation. We use nnU-Net as a baseline for organ segmentation.

from monai.networks.nets import UNet
from monai.losses import DiceCELoss
from monai.metrics import DiceMetric

model = UNet(
    spatial_dims=3,
    in_channels=1,
    out_channels=14,
    channels=(16, 32, 64, 128, 256),
    strides=(2, 2, 2, 2),
    num_res_units=2,
    dropout=0.1
)

criterion = DiceCELoss(
    include_background=False,
    to_onehot_y=True,
    softmax=True
)

The pretrained TotalSegmentator model segments 104 anatomical structures on CT. We fine-tune it for specific client tasks (e.g., pancreas segmentation accounting for positional variability).

from totalsegmentator.python_api import totalsegmentator
totalsegmentator(
    input='ct_scan.nii.gz',
    output='segmentations/',
    task='total',
    fast=False
)

Lung Nodule Detection: From LUNA16 to Production

Lung nodules are the first sign of lung cancer. The task: find nodules > 3 mm in a 3D volume. We build a pipeline: lung segmentation → detection (3D Retina U-Net) → postprocessing with clustering.

class NoduleDetector:
    def __init__(self, model_path: str, min_nodule_mm: float = 3.0, confidence_threshold: float = 0.5):
        self.model = load_nodule_model(model_path)
        self.min_size = min_nodule_mm
        self.threshold = confidence_threshold

    def detect(self, ct_volume: np.ndarray, voxel_spacing: tuple) -> list[dict]:
        lung_mask = self._segment_lung(ct_volume)
        nodule_mask = self.model.predict(ct_volume * lung_mask)
        nodules = self._extract_nodules(nodule_mask, voxel_spacing)
        return [n for n in nodules if n['diameter_mm'] >= self.min_size and n['confidence'] >= self.threshold]

What Does Quantitative Analysis Provide?

After segmentation, we measure organ and nodule volumes in ml, diameter per RECIST. This allows tracking tumor dynamics and evaluating therapy response.

def measure_volume_ml(mask: np.ndarray, voxel_spacing: tuple) -> float:
    voxel_volume_mm3 = np.prod(voxel_spacing)
    volume_mm3 = mask.sum() * voxel_volume_mm3
    return volume_mm3 / 1000

def measure_nodule_diameter(nodule_mask: np.ndarray, voxel_spacing: tuple) -> dict:
    coords = np.where(nodule_mask)
    from scipy.spatial import ConvexHull
    points = np.column_stack(coords) * np.array(voxel_spacing)
    if len(points) < 4:
        return {'diameter_mm': 0}
    hull = ConvexHull(points)
    max_dist = 0
    hull_pts = points[hull.vertices]
    for i in range(len(hull_pts)):
        for j in range(i+1, len(hull_pts)):
            d = np.linalg.norm(hull_pts[i] - hull_pts[j])
            max_dist = max(max_dist, d)
    return {'diameter_mm': round(max_dist, 2)}

What Metrics Guarantee Quality?

On public datasets, our model achieves the following results:

Task Dataset Metric Value
Lung segmentation LUNA16 Dice 0.98
Nodule detection LUNA16 FROC 0.89
Liver segmentation LiTS Dice 0.96
Liver tumor segmentation LiTS Dice 0.75
Multi-organ BTCV Dice 0.88

In production, we guarantee Dice no less than 0.95 for large organs and FROC > 0.85 for nodules. Each project is accompanied by a model card with metrics on stratified subgroups (age, sex, scanner type).

Process of Implementing an AI Module

Stage Duration Result
Data analysis 3–5 days Data quality report, annotation recommendations
Preprocessing and augmentation 5–7 days Loading and normalization pipeline
Model selection and training 2–4 weeks Baseline with metrics, final architecture selection
Validation on independent test set 1 week Model card, metrics report
Deployment and integration 1–2 weeks Docker image, Triton Inference Server, DICOM gateway
Post-release monitoring 3 months Logging, alerts, weekly reports

What Is Included in the Work

  • Development of a preprocessing pipeline specific to the scanner and protocol.
  • Selection and customization of architecture (nnU-Net, Retina U-Net, TotalSegmentator).
  • Training and validation with metrics tracking.
  • Containerization and deployment with Triton Inference Server.
  • Integration with PACS via DICOM gateway and HL7/FHIR.
  • Documentation: model card, operation manual, test report.
  • Client team training (2-3 hour workshop).
  • 3 months of post-release monitoring and support.

Our Experience and Guarantees

5+ years in the medical AI solutions market, 30+ completed projects in Russia and CIS. We guarantee quality: if metrics on the test set are below agreed thresholds, we refine for free. We provide a certificate of compliance with medical data processing standards. Development cost includes team training and 3 months of post-release monitoring.

Contact us — we will evaluate your data in 2 days, propose an architecture and realistic timelines. Order a pilot project: segmentation of one organ on 50 scans in 4 weeks.