RUNLOCALAIv38
->Will it run?Best GPUCompareTroubleshootStartLearnPulseModelsHardwareToolsBench
Run check
RUNLOCALAI

Independently operated catalog for local-AI hardware and software. Hand-written verdicts. Source-cited claims. Reproducible commands when we have them.

OP·Fredoline Eruo
DIR
  • Models
  • Hardware
  • Tools
  • Benchmarks
TOOLS
  • Will it run?
  • Compare hardware
  • Cost vs cloud
  • Choose my GPU
  • Prompting kits
  • Quick answers
REF
  • All buyer guides
  • Learn local AI
  • Methodology
  • Glossary
  • Errors KB
  • Trust
EDITOR
  • About
  • Author
  • How we make money
  • Editorial policy
  • Contact
LEGAL
  • Privacy
  • Terms
  • Sitemap
MAIL · MONTHLY DIGEST
Get monthly local AI changes
Monthly recap. No spam.
DISCLOSURE

Some links on this site are affiliate links (Amazon Associates and other first-class retailers). When you buy through them, we earn a small commission at no extra cost to you. Affiliate links do not influence our verdicts — there are cards we rate highly that we don't have affiliate relationships with, and cards that sell well that we refuse to recommend. Read more →

© 2026 runlocalai.coIndependently operated
RUNLOCALAI · v38
  1. >
  2. Home
  3. /Learn
  4. /Courses
  5. /Healthcare AI with Local Models
  6. /Ch. 10
Healthcare AI with Local Models

10. Medical Imaging Analysis

Chapter 10 of 18 · 20 min
KEY INSIGHT

Vision-language models detect obvious pathology with moderate reliability but miss subtle findings—use for prioritization and draft generation, not autonomous interpretation.

Medical imaging consumes significant radiology capacity. Chest X-rays, CT scans, and MRI studies require expert interpretation. Local AI models can assist by identifying findings, prioritizing worklists, and drafting preliminary reports.

Vision-language models (VLMs) handle imaging analysis by accepting images as input alongside text prompts. Ollama supports vision-capable models like Llama 3.2 Vision and specialized medical models.

# Install vision model for medical imaging
ollama pull llama3.2-vision

# Verify vision capability
ollama show llama3.2-vision
# medical_image_analyzer.py
import base64
from typing import Optional, List, Dict
from dataclasses import dataclass

@dataclass
class ImagingFinding:
    finding: str
    location: str
    severity: str
    description: str

class MedicalImageAnalyzer:
    """Analyze medical images using local vision-language model."""
    
    def __init__(self, ollama_client, model: str = "llama3.2-vision"):
        self.ollama = ollama_client
        self.model = model
        
    def analyze_chest_xray(self, image_path: str) -> Dict:
        """Analyze chest X-ray for common findings."""
        
        image_data = self._load_image_base64(image_path)
        
        prompt = """Analyze this chest X-ray and identify:
        1. Cardiomegaly
        2. Pneumonia/consolidation
        3. Pleural effusion
        4. Pneumothorax
        5. Pulmonary edema
        6. Lung nodules or masses
        
        For each finding present, describe location, severity, and key features.
        If normal, state "No acute cardiopulmonary abnormality identified."
        
        Output as structured JSON."""
        
        response = self.ollama.chat(
            model=self.model,
            messages=[{
                "role": "user",
                "content": prompt,
                "images": [image_data]
            }]
        )
        
        return self._parse_analysis_response(response["message"]["content"])
    
    def analyze_ct_head(self, image_path: str) -> Dict:
        """Analyze head CT for acute findings."""
        
        image_data = self._load_image_base64(image_path)
        
        prompt = """Analyze this head CT for acute findings:
        1. Intracranial hemorrhage
        2. Ischemic stroke signs
        3. Mass effect or midline shift
        4. Hydrocephalus
        5. Skull fracture
        
        Prioritize findings that require immediate clinical attention.
        Output as structured JSON with severity ratings."""
        
        response = self.ollama.chat(
            model=self.model,
            messages=[{
                "role": "user",
                "content": prompt,
                "images": [image_data]
            }]
        )
        
        return self._parse_analysis_response(response["message"]["content"])
    
    def prioritize_worklist(self, image_paths: List[str]) -> List[Dict]:
        """Prioritize imaging studies by likely urgency."""
        prioritized = []
        
        for path in image_paths:
            analysis = self.analyze_chest_xray(path)
            # Assign priority score based on findings
            priority = self._calculate_priority(analysis)
            prioritized.append({
                "path": path,
                "priority": priority,
                "findings": analysis
            })
        
        # Sort by priority descending
        prioritized.sort(key=lambda x: x["priority"], reverse=True)
        return prioritized
    
    def _load_image_base64(self, image_path: str) -> str:
        """Load image and convert to base64 for API."""
        with open(image_path, "rb") as f:
            return base64.b64encode(f.read()).decode("utf-8")
    
    def _parse_analysis_response(self, response: str) -> Dict:
        """Parse LLM analysis into structured format."""
        import json
        # Try JSON parsing first
        try:
            return json.loads(response)
        except:
            # Return as text if parsing fails
            return {"raw_analysis": response, "findings": []}
    
    def _calculate_priority(self, analysis: Dict) -> float:
        """Calculate urgency priority score."""
        critical_findings = [
            "pneumothorax", "hemorrhage", "acute stroke",
            "tension pneumothorax", "midline shift"
        ]
        
        findings = analysis.get("findings", [])
        for finding in findings:
            if any(cf in str(finding).lower() for cf in critical_findings):
                return 1.0
        
        # Check severity field
        severity = analysis.get("severity", "low")
        severity_map = {"critical": 1.0, "high": 0.8, "moderate": 0.5, "low": 0.2}
        return severity_map.get(severity, 0.3)

Medical imaging analysis faces specific challenges: subtle findings that distinguish normal from abnormal require fine-tuned models. General-purpose vision models perform reasonably on obvious pathology but miss subtle abnormalities. Consider fine-tuning or using medically-specialized models for production systems.

EXERCISE

Collect ten chest X-rays with known findings. Run analysis on each and compare to ground truth. Calculate sensitivity for each finding type and identify systematic weaknesses.

← Chapter 9
Drug Interaction Checking
Chapter 11 →
Radiology Report Drafting