CervicalDoctor
CervicalDoctor provides one complete single-patient pipeline and four independent tasks:
import CervicalDoctor
CervicalDoctor.pipeline(...)
CervicalDoctor.detect(...)
CervicalDoctor.acetic(...)
CervicalDoctor.seg(...)
CervicalDoctor.classify(...)
The diagnosis class order is always Ca, HSIL, LSIL, Normal. Python reserves the word class, so
the public diagnosis function is named classify.
Installation and model assets
Install the code package from PyPI:
pip install CervicalDoctor
The PyPI wheel intentionally does not contain the approximately 17 GB model bundle. Until the model
bundle is published separately, point the installed package at an existing CervicalDoctor asset
directory whose direct child is ckpt/:
export CERVICALDOCTOR_HOME=/path/to/CervicalDoctor-assets
The source checkout detects its own ckpt/ automatically. Installed builds otherwise look under
~/.cache/cervicaldoctor/. A missing model raises an explicit error showing the expected path.
Input contract
Except for standalone acetic, image_path may be either:
- one
.jpg,.jpeg,.png,.bmp,.dcm, or.dicomfile; or - one folder whose direct image children all belong to the same patient.
Input folders are deliberately not scanned recursively. Standalone acetic requires a folder even
when it contains only one image. A folder containing no supported direct image files is rejected.
Complete pipeline
result = CervicalDoctor.pipeline(
image_path="case_001",
txt_path=None,
filter=True,
conf=0.25,
out_dir=None,
device="cuda",
)
When filter=True, every image is passed through cervix detection and acetic-image classification.
Only original images satisfying both conditions continue:
at least one cervix detection AND acetic top-1 == vinegar
Detection visualizations are never sent to segmentation or diagnosis. When filter=False, both
dirty-data checks are skipped and every original input image continues directly. Segmentation is
mandatory in both modes because the released diagnosis model was trained with binary lesion masks.
If filtering keeps no image, the result has status="no_eligible_images" and no diagnosis is
fabricated.
The default folder-input output is <image_path>/cervicaldoctor_output. A typical result is:
cervicaldoctor_output/
├── detect/
│ ├── image_1.jpg.detected.png
│ ├── image_2.png.detected.png
│ └── detect.json
├── acetic/
│ ├── image_2.png
│ └── acetic.json
├── filtered/
│ └── image_2.png
├── classification/
│ ├── segmentation/
│ │ ├── masks/
│ │ │ └── image_2.png.mask.png
│ │ ├── overlays/
│ │ │ └── image_2.png.overlay.png
│ │ └── segmentation.json
│ └── prediction.json
├── filter.json
└── pipeline_result.json
For a single-file input, the default is a sibling folder such as
image_1_cervicaldoctor_output/. Pass out_dir to choose another location. Existing output is
protected unless overwrite=True is set.
Independent tasks
Cervix detection
result = CervicalDoctor.detect(
image_path="case_001", # file or folder
conf=0.25,
out_dir="detect_output",
device="cuda",
)
Every input image/frame receives a .detected.png visualization, including images with no box.
detect.json and the returned dictionary contain box coordinates, confidence, has_cervix, source
identity, and visualization path.
Acetic-image selection
result = CervicalDoctor.acetic(
image_path="case_001", # folder is required
out_dir="acetic_output",
device="cuda",
)
The output folder contains zero or more original images whose top-1 class is vinegar, plus
acetic.json. This independent task does not require a cervix detection; the intersection rule is
applied only by pipeline(filter=True).
Binary lesion segmentation
result = CervicalDoctor.seg(
image_path="case_001", # file or folder
out_dir="seg_output",
device="cuda",
)
masks/ contains binary PNG masks with 0=background and 255=lesion. overlays/ contains green
mask-on-original visualizations. segmentation.json maps every artifact to its source image/frame.
Patient diagnosis
result = CervicalDoctor.classify(
image_path="case_001", # file or folder; all images are one patient
txt_path="txt.json", # or None
out_dir="classify_output",
device="cuda",
)
classify always invokes the public binary segmenter internally. There is no public switch to skip
segmentation and no external mask_path argument. Multiple images are pooled into one patient-level
diagnosis. The return value includes probabilities, per-image attention, source gates, text gate,
the complete internal segmentation manifest, and the epoch-16 all-data checkpoint identity.
Clinical JSON and cache
txt_path=None means age, HPV, and cytology are all unavailable. Its HealthGPT feature is shipped
as a precomputed release cache, so the 8B text encoder is not loaded.
A clinical JSON contains one patient's data:
{
"age": 45,
"hpv": "HPV16 positive",
"cytology": "HSIL"
}
The legacy keys hpv_standardization and cytology_standardization are also accepted. The JSON is
reread on every call. Cache identity is computed from the normalized prompt content rather than the
file path:
- unchanged content reuses
cache/inference_text/<content-hash>.pt; - changed content generates a different key and feature;
- the first unseen prompt loads HealthGPT; later calls do not.
BMP and DICOM
BMP is decoded as an ordinary RGB raster. DICOM decoding handles:
- uncompressed and supported compressed pixel data;
- grayscale rescale, VOI LUT/windowing, and
MONOCHROME1inversion; - RGB and YBR color conversion;
- single-frame and multi-frame objects.
Each multi-frame DICOM frame is treated as one image belonging to the same patient. A safety limit of 64 frames prevents accidental ingestion of long videos. DICOM is converted to temporary RGB PNG only for model execution; temporary files are removed after the task. Detector and segmentation visualizations are always PNG. Accepted single-frame DICOM files remain DICOM; accepted frames from a multi-frame object are materialized as RGB PNG files so rejected frames cannot re-enter the next stage.
Format support does not make the model clinically calibrated for unrelated grayscale modalities. The released diagnosis model was trained on colposcopy imagery.
Device
The NVIDIA build accepts:
cpu
cuda
cuda:N
auto
Top-level functions default to cuda. auto selects CUDA when torch.cuda.is_available() is true.
Dynamic uncached clinical text is technically supported on CPU but loading HealthGPT-Pro-8B is slow
and memory intensive. txt_path=None avoids that load through the release cache.
An instance can reuse lazy-loaded models:
doctor = CervicalDoctor.CervicalDoctor(device="cuda")
first = doctor.pipeline("case_001", filter=True)
second = doctor.classify("case_002", txt_path=None)
doctor.release()
Active checkpoints
All active runtime assets are under ckpt/:
ckpt/cervicaldc/: cervix detector and acetic-image classifier;ckpt/cervicalseg-v0.2.0/: binary lesion checkpoint used bycervicalseg>=0.2.0;ckpt/cervicaldoctor/weights_full_final_epoch_016.pt: the only active diagnosis weight;ckpt/cervicaldoctor/text_cache/: release cache for missing clinical information;ckpt/dinov3-vits16-pretrain-lvd1689m/: local DINOv3 model;ckpt/healthgpt-pro-8b/: local HealthGPT text encoder.
Patient-split and resumable full-training checkpoints are stored under backups/ and are never
loaded by the public API. CervicalDC's required Ultralytics runtime is integrated under
cervical_doctor/_vendor/; the package does not import the sibling CervicalDC project.
Verification
Run API/model contract tests:
python scripts/run_smoke_tests.py
Verify every declared model asset:
python scripts/verify_assets.py
Training source
The original patient-level training implementation remains available through train.py and
train_full.py. The release diagnosis weight was trained for 16 epochs on the filtered
train+validation+test union after epoch count selection by the preceding patient-split experiment.
The active model uses DINOv3 ViT-S/16, binary CervicalSeg lesion ROI weights, Haar LH/HL/HH sources,
per-image five-source gating, patient attention MIL, and frozen HealthGPT clinical features.
The code package is distributed independently from the large model assets. Hugging Face model publishing and automatic asset download can be added without changing the public inference API.
Metadata
Release files for CervicalDoctor 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cervicaldoctor-0.4.0.tar.gz | 1.1 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cervicaldoctor-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.5 MB
Release files / cervicaldoctor-0.4.0.tar.gz
| Download URL | cervicaldoctor-0.4.0.tar.gz |
|---|---|
| Size | 1.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
88d48eef785b8d932898685b8e0fcc764085cc06c2fbea081fd439fc38d7fa6c
|
|
BLAKE2b-256 checksum How to use checksums |
68f81c5a43a8a0ace2e2c4a3c10e157ef39d30736c1ad21bd77a7d7af7e1b0d0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.12
|
Release files / cervicaldoctor-0.4.0-py3-none-any.whl
| Download URL | cervicaldoctor-0.4.0-py3-none-any.whl |
|---|---|
| Size | 1.4 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a9c8e86c4170008ac3bacdca5c154d24d71394fbde19fedd0f71f642b4d07347
|
|
BLAKE2b-256 checksum How to use checksums |
5b19c8e25cdf80004a9396dd1cac98fde77d615d0c89af6e736fd4899aab730d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.12
|