Skip to page content
SAVRN
Search Plan a project

Dataset · Object detection

open-radiograph-findings

by Dylan Tirandaz tirandazdylan/open-radiograph-findings

Source data for the radiograph-dicom-ingest Verifiers environment. Each row is one radiograph with: - the image file exactly as the source distributes it (GRAZPEDWRI-DX 16-bit PNG, FracAtlas JPEG; bytes are not re-encoded), - the source annotation files for…

Rows1,702
Configurations1
Size1.1 GB
Licensecc-by-4.0
AccessPublicly accessible
Monthly Downloads—

Dataset Card

By Dylan Tirandaz, published under cc-by-4.0, revision 20f26bf9436b.

Radiograph DICOM Ingest

Source data for the radiograph-dicom-ingest Verifiers environment. Each row is one radiograph with:

  • the image file exactly as the source distributes it (GRAZPEDWRI-DX 16-bit PNG, FracAtlas JPEG; bytes are not re-encoded),
  • the source annotation files for that image, verbatim (Pascal VOC XML, YOLO txt, Supervisely JSON, COCO entries),
  • normalized bounding boxes derived from the source YOLO labels.

The dataset contains no DICOM files. It is a research and benchmarking resource and is not for clinical use.

split GRAZPEDWRI-DX rows (patients) FracAtlas rows total
train 1,029 (304) 344 1,373
test 273 (66) 56 329
total 1,302 (370) 400 1,702

Sources and license

Both sources are published under CC BY 4.0, and this subset is released under the same license. Changes from the sources: a subset of images was selected, the files were repackaged into Parquet, and a normalized objects column was derived from the YOLO labels. Image bytes and annotation text are unchanged.

source figshare article files used (figshare file id, published MD5)
GRAZPEDWRI-DX 14825193 v2 dataset.csv (35026432, f2e996300443654faa62983b7ef1b4c1), folder_structure.zip (34268819, e484b434286428750e9c838a7ed6ada7), images_part1.zip (34268828), images_part2.zip (34268849), images_part3.zip (34268864), images_part4.zip (34268891)
FracAtlas 22363012 v7 FracAtlas.zip (65518038, fe9da2c7c285915ebee69dfdab8fd396)

The build checks the MD5 of dataset.csv, folder_structure.zip and FracAtlas.zip. The four GRAZPEDWRI-DX image zips (about 4 GB each) were not downloaded in full. The selected PNG members were read with HTTP range requests, and each one passed the zip CRC-32 check. By patient id range, the image zips hold: part1 0001–1499, part2 1500–2999, part3 3000–4499, part4 4500–6093.

  • GRAZPEDWRI-DX: Nagy E, Janisch M, Hržić F, Sorantin E, Tschauner S. A pediatric wrist trauma X-ray dataset (GRAZPEDWRI-DX) for machine learning. Scientific Data 9, 222 (2022). https://doi.org/10.1038/s41597-022-01328-z
  • FracAtlas: Abedeen I, Rahman MA, Prottyasha FZ, Ahmed T, Chowdhury TM, Shatabda S. FracAtlas: A Dataset for Fracture Classification, Localization and Segmentation of Musculoskeletal Radiographs. Scientific Data 10, 521 (2023). https://doi.org/10.1038/s41597-023-02432-4

Selection rule

Split assignment is the same for both sources:

split = "test" if int(hashlib.md5(key.encode("utf-8")).hexdigest(), 16) % 100 < 15 else "train"

GRAZPEDWRI-DX (key = str(patient_id), the integer in dataset.csv without zero padding, for example "1"):

  1. The rule splits the 6,091 patients into a train pool of 5,221 and a test pool of 870.
  2. rng = random.Random(0), then rng.sample(sorted(train_pool), 300) and rng.sample(sorted(test_pool), 60), in that order.
  3. Class-coverage top-up, using the same rng: for each of the 9 YOLO classes in alphabetical order, and for each split in the order (train, test), the build checks how many selected patients have at least one Supervisely object of that class. If fewer than 2 do, it adds rng.sample(sorted(unselected pool patients with the class), min(missing, available)). This added boneanomaly/test 1159 and 4903; bonelesion/train 2946 and 3855; bonelesion/test 5182 and 5987; foreignbody/train 1237 and 6081; and metal/test 1524 and 4089. The test pool contains no foreignbody patients. The final selection is 304 train and 66 test patients.
  4. Every image of a selected patient is included (all studies and projections), so no patient appears in both splits.

FracAtlas (key = image stem, for example "IMG0000019"). FracAtlas publishes no patient identifiers. patient_id is therefore the image id and the split is made per image, so images of one patient can appear in both splits.

  1. The candidates are the 4,083 dataset.csv rows. Each image is read from images/Fractured/ or images/Non_fractured/ according to the fractured flag in the CSV. Two groups are excluded: - 25 images (23 non-fractured, 2 fractured) have an EXIF Orientation tag other than 1. datasets.Image applies exif_transpose when decoding, and at least one annotated image (IMG0002628) is labelled in the rotated frame. - 59 non-fractured JPEGs are truncated and cannot be fully decoded (IMG0004028 to IMG0004347; the full list is in the build report).
  2. rng = random.Random(0), then rng.sample(sorted(fractured), 200) followed by rng.sample(sorted(non_fractured), 200).
  3. The split is assigned by the hash rule, giving train 344 (177 fractured) and test 56 (23 fractured).

Columns

column type content
image Image Source file bytes, unmodified. GRAZPEDWRI-DX is 16-bit grayscale PNG (decodes as PIL mode I;16). FracAtlas is 8-bit JPEG, either RGB or L (358 baseline, 42 progressive).
image_id string Source file stem, such as 0001_1297860435_01_WRI-L2_M014 or IMG0000019.
source string graz or fracatlas.
split string train or test. This matches the Parquet split.
patient_id string GRAZPEDWRI-DX patient_id as text ("1"). For FracAtlas, the image id.
width, height int32 Pixel size of the stored image, read from the PNG IHDR or the JPEG SOF.
bit_depth int32 Bits per sample: 16 for GRAZPEDWRI-DX, 8 for FracAtlas.
pixel_spacing float64 GRAZPEDWRI-DX pixel_spacing column in mm (0.144 or 0.143). Null for FracAtlas.
laterality string GRAZPEDWRI-DX laterality (L/R). Null for FracAtlas.
projection string GRAZPEDWRI-DX projection code, verbatim: 1 = AP, 2 = lateral, 3 = oblique. These match the Supervisely tags projection_ap, projection_lat and projection_oblique. Null for FracAtlas.
objects struct label: list[string] and box: list[[x1, y1, x2, y2]] (float64, normalized). See Box convention below.
voc_xml string Source Pascal VOC XML, verbatim.
yolo_txt string Source YOLO label file, verbatim. Empty for FracAtlas non-fractured images.
supervisely_json string Source Supervisely annotation, verbatim. GRAZPEDWRI-DX only.
coco_annotations string JSON list of the entries in FracAtlas COCO_fracture_masks.json whose image_id points at this image ([] when there are none). image_id inside each entry is the COCO file's internal id, and category_id 1 is fractured. FracAtlas only.

Box convention

objects.box holds [x1, y1, x2, y2] normalized by the stored image's width and height. In pixels, the box is x1 * width, y1 * height and so on, in continuous 0-based coordinates: 0 is the left or top edge of the first pixel and width is the right edge of the last. The boxes come from the YOLO files. For each line class cx cy w h: x1 = cx - w/2, y1 = cy - h/2, x2 = cx + w/2, y2 = cy + h/2. Each value is clipped to [0, 1] and rounded to 7 decimals. Labels are the source class names:

  • GRAZPEDWRI-DX: yolov5/meta.yaml lists boneanomaly, bonelesion, foreignbody, fracture, metal, periostealreaction, pronatorsign, softtissue and text. text marks burned-in text and side markers. The YOLO box equals the Supervisely rectangle points (or polygon extent) divided by the image size, with no +1 width convention. Across all 20,327 source files the two agree within 0.0015 px. Periosteal reaction and bone lesion are polygons in Supervisely, and objects holds their axis-aligned extent. Supervisely axis objects (a bone-axis line, one per image) have no YOLO or VOC box and appear only in supervisely_json.
  • FracAtlas: the single class is fractured. The YOLO box equals the COCO bbox [x, y, w, h], which is float and 0-based, divided by the image size (within 0.0021 px in this subset).

The build cross-checks VOC against YOLO in pixel space for every row. It requires the same label multiset, matches boxes greedily within each label, and flags any coordinate that differs by more than 1 px.

  • GRAZPEDWRI-DX VOC holds integer 0-based coordinates: the Supervisely coordinates truncated toward zero, with no 1-based shift. This holds exactly in all 20,327 files. Rows with fractional Supervisely rectangles, mostly text, therefore differ by less than 1 px. In this subset the maximum is 0.998 px, and 195 of 1,302 images have a box more than 0.5 px off. No row exceeds 1 px and there are no label mismatches.
  • FracAtlas VOC holds the COCO corners rounded half-up. The maximum difference is 0.50 px, with no label mismatches.

Counts

Object instances, with the number of images containing the class in parentheses:

source class train test
graz boneanomaly 19 (16) 4 (4)
graz bonelesion 3 (3) 2 (2)
graz foreignbody 4 (4) 0 (0)
graz fracture 888 (642) 288 (196)
graz metal 13 (12) 11 (10)
graz periostealreaction 183 (133) 70 (39)
graz pronatorsign 28 (28) 9 (9)
graz softtissue 25 (25) 7 (6)
graz text 1,178 (1,028) 311 (272)
fracatlas fractured 224 (177) 30 (23)
  • Image-level labels. GRAZPEDWRI-DX fracture_visible = 1 in 642 train and 196 test images. It is blank (negative) in 387 train and 77 test images, and in this subset it agrees exactly with the presence of a fracture box. FracAtlas has 177 train and 23 test images with fractured = 1; the other 200 have no boxes. Fractured FracAtlas images carry 1 box (153), 2 (42), 3 (3) or 4 (2).
  • Supervisely objects (GRAZPEDWRI-DX). There are 1,302 axis lines, one of them drawn with more than 2 points. Polygon objects are periostealreaction (253) and bonelesion (5).
  • Image properties.
property GRAZPEDWRI-DX (1,302 PNGs) FracAtlas (400 JPEGs)
format 16-bit grayscale (color type 0) 8-bit: 326 RGB, 74 L
pixel maximum 65,534–65,535 (full 16-bit range) 172–255
size range 227–1,383 × 364–2,068 px 373–2,880 px on each side
  • GRAZPEDWRI-DX metadata. Pixel spacing is 0.144 mm (1,288 images) or 0.143 mm (14). Laterality is L 654, R 648. Projection is 1 (AP) 648, 2 (lateral) 646, 3 (oblique) 8.

Source anomalies

GRAZPEDWRI-DX (the label-file checks cover all 20,327 files):

  • Every VOC file has an empty <size/>, so the image size must come from the PNG or from the Supervisely size. They always agree in this subset.
  • Every VOC file is pretty-printed with whitespace-padded text nodes (for example <name>\n text\n </name>). Strip the whitespace before use.
  • In 5467_0365242890_01_WRI-R1_M010, VOC and Supervisely have a metal box covering the full image height that YOLO omits. This image is not in the subset.
  • VOC and YOLO differ by at most 1.000005 px across all files, in one text box of 2047_0885653401_01_WRI-R2_M013 (not in the subset). The cause is the integer truncation described above.
  • 491 YOLO boxes (32 in the subset) overshoot [0, 1] by at most 5e-7 because of 6-decimal rounding. They are clipped.
  • dataset.csv starts with a UTF-8 BOM (filestem). yolov5/meta.yaml has FILL IN placeholder paths.

FracAtlas:

  • IMG0003375.jpg and IMG0003376.jpg exist in both images/Fractured/ and images/Non_fractured/. The copies are byte-identical, and dataset.csv marks both as fractured. This is why Non_fractured/ has 3,366 files for 3,364 non-fractured CSV rows. This dataset reads each image from the folder its CSV flag names. IMG0003375 is in the subset.
  • 59 JPEGs are truncated (all non-fractured, IMG0004028 to IMG0004347) and were excluded.
  • 25 images carry EXIF Orientation 3, 6 or 8 and were excluded. For IMG0002628 (orientation 8, fractured), the VOC and COCO width and height are swapped relative to the stored JPEG. Three selected images carry Orientation 1 (identity) and were kept.
  • Annotations/YOLO/ contains an extra labels.txt (fractured\r\n), so it has 4,084 files against 4,083 VOC files.
  • VOC <depth> is 3 for every selected image, including the 74 single-channel (L) JPEGs.

Usage

from datasets import load_dataset, Image

ds = load_dataset("path/or/repo", split="train")
row = ds[0]
row["image"]                      # PIL image; GRAZPEDWRI-DX PNGs decode as mode "I;16"
x1, y1, x2, y2 = row["objects"]["box"][0]
pixel_box = (x1 * row["width"], y1 * row["height"], x2 * row["width"], y2 * row["height"])

raw = ds.cast_column("image", Image(decode=False))[0]["image"]["bytes"]  # original file bytes

Reproduce

The build uses Python 3.12 with datasets 5.0.1, pyarrow 25.0.1, pandas 3.0.6, numpy 2.5.3 and Pillow 12.3.0. scripts/build_dataset.py downloads nothing except the ranged reads of the selected GRAZPEDWRI-DX PNGs.

mkdir -p /tmp/rr-src /tmp/rfd/src
curl -L -o /tmp/rr-src/graz_dataset.csv https://ndownloader.figshare.com/files/35026432
curl -L -o /tmp/rr-src/graz_folder.zip  https://ndownloader.figshare.com/files/34268819
curl -L -o /tmp/rfd/src/FracAtlas.zip   https://ndownloader.figshare.com/files/65518038
python scripts/build_dataset.py --graz-csv /tmp/rr-src/graz_dataset.csv \
  --graz-labels /tmp/rr-src/graz_folder.zip --fracatlas-zip /tmp/rfd/src/FracAtlas.zip \
  --work /tmp/rfd/work --out /tmp/rfd/hf
python scripts/build_dataset.py --verify-only --work /tmp/rfd/work --out /tmp/rfd/hf

The build writes data/ and scripts/ and leaves this README in place. --work receives the PNG cache, report.json (selection, statistics and source audit) and rows.jsonl, which holds one summary per row including the SHA-256 of each image. Verification resolves the splits from this README with datasets and checks that the stored features match. It then streams every row group and checks each row: the image SHA-256, the size decoded by datasets.Image against width and height, and that each box lies within the unit square.

Citation

@article{nagy2022grazpedwri,
  title   = {A pediatric wrist trauma X-ray dataset (GRAZPEDWRI-DX) for machine learning},
  author  = {Nagy, Eszter and Janisch, Michael and Hr{\v{z}}i{\'c}, Franko and Sorantin, Erich and Tschauner, Sebastian},
  journal = {Scientific Data},
  volume  = {9},
  pages   = {222},
  year    = {2022},
  doi     = {10.1038/s41597-022-01328-z}
}

@article{abedeen2023fracatlas,
  title   = {FracAtlas: A Dataset for Fracture Classification, Localization and Segmentation of Musculoskeletal Radiographs},
  author  = {Abedeen, Iftekharul and Rahman, Md. Ashiqur and Prottyasha, Fatema Zohra and Ahmed, Tasnim and Chowdhury, Tareque Mohmud and Shatabda, Swakkhar},
  journal = {Scientific Data},
  volume  = {10},
  pages   = {521},
  year    = {2023},
  doi     = {10.1038/s41597-023-02432-4}
}

Structure

default 1,702 rows

SplitRowsSize
train1,373864.4 MB
test329210.8 MB
imageImageimage_idstringsourcestringsplitstringpatient_idstringwidthint32heightint32bit_depthint32pixel_spacingfloat64lateralitystringprojectionstringobjectsvaluevoc_xmlstringyolo_txtstringsupervisely_jsonstringcoco_annotationsstring

Details

Repository
tirandazdylan/open-radiograph-findings
Publisher
Dylan Tirandaz
Task category
Object detection
Tags
medical, radiology, radiograph
Size category
1K<n<10K
Languages
Not stated by the source
Revision
20f26bf9436b23af8b6f9ae171f96d86f837bb17
Last updated
2026-09-28

Files

6 files, 1.1 GB in total.

Data3 files · 1.1 GB
Documentation1 file · 15.4 KB
Other1 file · 35.1 KB
Repository1 file · 2.5 KB
Every file
FileTypeSizeSHA-256
data/test-00000-of-00001.parquetData210.4 MBa3d8471e7ab4
data/train-00000-of-00002.parquetData431.6 MB9e4714a57db0
data/train-00001-of-00002.parquetData431.0 MBa5b0f4fc99fd
README.mdDocumentation15.4 KB—
scripts/build_dataset.pyOther35.1 KB—
.gitattributesRepository2.5 KB—

License and Download

License
cc-by-4.0
Access
No access gate
Download from Dylan Tirandaz

Released by Dylan Tirandaz through its official repository on Hugging Face. Read the license.