XraySorterAI (ONNX)
ONNX export of the XraySorterAI Xception classifiers for projection (45 classes) and body side in musculoskeletal radiographs. Original work: https://github.com/maxrusse/XraySorterAI.
โ ๏ธ Not for medical use. Research/demonstration only; not for clinical or diagnostic decisions. Make sure you have the rights to any images you use and that they contain no personal identifiers.
Files
| File | Description |
|---|---|
onnx/projection.onnx |
projection classifier, 45 outputs |
onnx/side.onnx |
body-side classifier, 12 outputs (labels alternate right/left, as in the original code) |
config.json |
labels, I/O spec, SHA-256 of each model |
inference.py |
TensorFlow-free inference (ONNX Runtime + OpenCV + NumPy) |
Model I/O
- Input
pixels:float32 [N, 256, 256, 3](NHWC), values 0..255, dynamic batch. Xception normalisation (x/127.5 - 1) is inside the graph. - Output: softmax probabilities.
- The 3 channels are produced by
inference.preprocess(adaptive threshold, raw, inverted) โ use it rather than a plain RGB image.
Usage
python -m pip install -r requirements.txt # in a uv venv use: uv pip install -r requirements.txt
python inference.py scan.dcm scan.png scan.nii.gz
from inference import XraySorter
sorter = XraySorter(".")
print(sorter.predict("scan.dcm")) # also .png/.nii.gz, PIL.Image, pydicom Dataset, NumPy array
# {'projection': {'label': 'ap_knee', 'confidence': 0.99}, 'side': {'label': 'bodyside_left', 'confidence': 0.98}}
Input conventions (important)
inference.py handles two properties of the training data for you. Both are on by default:
- Intensity range. The preprocessing is intensity-scale dependent and the models were trained on
high-bit-depth data (~12-bit). 8-bit inputs (JPEG, 8-bit PNG,
uint8arrays, 8-bit PIL) are multiplied by 16 on load (promote_8bit=True). Disable withXraySorter(".", promote_8bit=False). - Orientation. The models were trained on NIfTI arrays indexed (x, y), not upright images. Upright inputs
(PNG, JPEG, DICOM, PIL, NumPy: rows top to bottom as displayed) are converted with an anti-transpose
(
np.rot90(a, 2).T). NIfTI files are loaded in the native orientation and left untouched. Disable withupright=Falseif you already feed NIfTI-oriented arrays.
On a small local set of 14 web-sourced test radiographs (not distributed), projection accuracy is 0/14 without either step, 9/14 with the range fix only and 13/14 with both. Skipping the orientation step also makes the side model unreliable.
Efficiency notes: sessions are built once, preprocessing is shared by both models, batches are supported, no TensorFlow / tf-explain dependency (Grad-CAM is not included in this export).
Conversion
Produced with export.py (tf2onnx, opset 17); outputs were verified against the Keras models.
- Downloads last month
- -