WZMIAOMIAO/deep-learning-for-image-processing · error · ValueError

Image '{}' format not JPEG

Error message

Image '{}' format not JPEG

What it means

SSD's VOCDataSet.__getitem__ opens each image with PIL and asserts the format is JPEG before parsing boxes. PNG, GIF, or other formats raise ValueError because the training pipeline (and its standard transformations) assume JPEG-encoded images typical of VOC datasets.

Source

Thrown at pytorch_object_detection/ssd/my_dataset.py:52

        self.transforms = transforms

    def __len__(self):
        return len(self.xml_list)

    def __getitem__(self, idx):
        # read xml
        xml_path = self.xml_list[idx]
        with open(xml_path) as fid:
            xml_str = fid.read()
        xml = etree.fromstring(xml_str)
        data = self.parse_xml_to_dict(xml)["annotation"]
        data_height = int(data["size"]["height"])
        data_width = int(data["size"]["width"])
        height_width = [data_height, data_width]
        img_path = os.path.join(self.img_root, data["filename"])
        image = Image.open(img_path)
        if image.format != "JPEG":
            raise ValueError("Image '{}' format not JPEG".format(img_path))

        assert "object" in data, "{} lack of object information.".format(xml_path)
        boxes = []
        labels = []
        iscrowd = []
        for obj in data["object"]:
            # 将所有的gt box信息转换成相对值0-1之间
            xmin = float(obj["bndbox"]["xmin"]) / data_width
            xmax = float(obj["bndbox"]["xmax"]) / data_width
            ymin = float(obj["bndbox"]["ymin"]) / data_height
            ymax = float(obj["bndbox"]["ymax"]) / data_height

            # 进一步检查数据,有的标注信息中可能有w或h为0的情况,这样的数据会导致计算回归loss为nan
            if xmax <= xmin or ymax <= ymin:
                print("Warning: in '{}' xml, there are some bbox w/h <=0".format(xml_path))
                continue
                
            boxes.append([xmin, ymin, xmax, ymax])

View on GitHub (pinned to 1ec3fe6f37)

Solutions

  1. Convert non-JPEG images to JPEG in place (PIL Image.open(...).convert('RGB').save(path, 'JPEG'))
  2. Remove non-image or non-JPEG files from the images root (e.g. index.html artifacts)
  3. Add a preprocessing script that scans Image.format and reports offending files before training

Example fix

// before
image = Image.open(img_path)
if image.format != 'JPEG': raise ValueError(...)
// after (preprocess)
for p in all_images:
    im = Image.open(p)
    if im.format != 'JPEG':
        im.convert('RGB').save(p, 'JPEG')
Defensive patterns

Strategy: validation

Validate before calling

from PIL import Image
import os
bad = [f for f in os.listdir(img_root)
       if Image.open(os.path.join(img_root, f)).format != 'JPEG']
assert not bad, f'Non-JPEG images present: {bad[:5]}'

Type guard

def is_jpeg(path: str) -> bool:
    with Image.open(path) as im:
        return im.format == 'JPEG'

Try / catch

try:
    image, target = dataset[idx]
except ValueError as e:
    print(f'Dataset contains non-JPEG image: {e}')

Prevention

When it happens

Trigger: An image referenced by an annotation XML in the dataset folder is not JPEG (e.g. a PNG or webp saved into the JPEGs folder); index.html or corrupt files mixed into the images directory.

Common situations: Downloading images from the web into the VOC JPEGImages folder; some VOC-style datasets (e.g. custom datasets converted from PNG) lacking JPEGs; manually adding screenshots or icons.

Related errors


AI-assisted analysis of WZMIAOMIAO/deep-learning-for-image-processing@1ec3fe6f37 (2026-08-30). Data as JSON: /api/errors/24e5ee92367e75cf. Report an issue: GitHub.