PaddlePaddle/PaddleOCR · error · Exception

lam must be number or list with length 2

Error message

lam must be number or list with length 2

What it means

CVPossionNoise's constructor validates lam (Poisson lambda): a number is sampled via sample_asym, a 2-element tuple/list via sample_uniform, and anything else raises Exception('lam must be number or list with length 2'). The misspelled class name (Possion) and the parameter name lam both appear verbatim in configs, so the message text is accurate here.

Source

Thrown at ppocr/data/imaug/abinet_aug.py:323

            self.var = int(sample_uniform(var[0], var[1]))
        else:
            raise Exception("degree must be number or list with length 2")

    def __call__(self, img):
        noise = np.random.normal(self.mean, self.var**0.5, img.shape)
        img = np.clip(img + noise, 0, 255).astype(np.uint8)
        return img


class CVPossionNoise(object):
    def __init__(self, lam=20):
        self.lam = lam
        if isinstance(lam, numbers.Number):
            self.lam = max(int(sample_asym(lam)), 1)
        elif isinstance(lam, (tuple, list)) and len(lam) == 2:
            self.lam = int(sample_uniform(lam[0], lam[1]))
        else:
            raise Exception("lam must be number or list with length 2")

    def __call__(self, img):
        noise = np.random.poisson(lam=self.lam, size=img.shape)
        img = np.clip(img + noise, 0, 255).astype(np.uint8)
        return img


class CVGaussionBlur(object):
    def __init__(self, radius):
        self.radius = radius
        if isinstance(radius, numbers.Number):
            self.radius = max(int(sample_asym(radius)), 1)
        elif isinstance(radius, (tuple, list)) and len(radius) == 2:
            self.radius = int(sample_uniform(radius[0], radius[1]))
        else:
            raise Exception("radius must be number or list with length 2")

    def __call__(self, img):

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Pass lam as a number (e.g. lam=20) or a 2-element tuple like lam=(5, 30).
  2. Cast scalars from config: lam=float(cfg['lam']).
  3. Keep range specs to exactly (low, high).

Example fix

# before
CVPossionNoise(lam=cfg['lam'])  # cfg['lam'] == '20' -> Exception
# after
lam = cfg['lam']
CVPossionNoise(lam=float(lam) if isinstance(lam, (int, float)) else (lam[0], lam[1]))
Defensive patterns

Strategy: validation

Validate before calling

import numbers

def valid_lam(v) -> bool:
    return (isinstance(v, numbers.Number)
            or (isinstance(v, (tuple, list)) and len(v) == 2))

Type guard

import numbers

def is_valid_lam(v) -> bool:
    return isinstance(v, numbers.Number) or (isinstance(v, (tuple, list)) and len(v) == 2)

Prevention

When it happens

Trigger: CVPossionNoise(lam=[5, 10, 20]) (length 3), lam='20' (string), lam=None or a dict from config.

Common situations: YAML/JSON numeric values loading as strings; range specs with more than two bounds; copying configs between noise transforms with different parameter shapes.

Related errors


AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14). Data as JSON: /api/errors/05e531426e585403. Report an issue: GitHub.