Skip to content

synthetic_detection

orchard.data_handler.diagnostic.synthetic_detection

Synthetic Detection Data for Testing.

Generates random images with bounding-box annotations for detection task unit tests. Follows the same pattern as :func:create_synthetic_dataset for classification.

SyntheticDetectionData(image_path, annotation_path, num_classes, name)

Container for synthetic detection dataset paths and metadata.

Attributes:

Name Type Description
image_path Path

Path to images NPZ.

annotation_path Path

Path to annotations NPZ.

num_classes int

Number of object classes (excluding background).

name str

Dataset identifier.

Source code in orchard/data_handler/diagnostic/synthetic_detection.py
def __init__(
    self,
    image_path: Path,
    annotation_path: Path,
    num_classes: int,
    name: str,
) -> None:
    self.image_path = image_path
    self.annotation_path = annotation_path
    self.num_classes = num_classes
    self.name = name

create_synthetic_detection_dataset(num_classes=4, samples=50, resolution=64, channels=3, name='synthetic_detection')

Create a synthetic detection dataset for testing.

Generates random images with random bounding boxes and saves them as NPZ files (images + annotations separately).

Parameters:

Name Type Description Default
num_classes int

Number of object categories (default: 4).

4
samples int

Number of training images (default: 50).

50
resolution int

Image size in pixels (default: 64).

64
channels int

Color channels (default: 3).

3
name str

Dataset identifier (default: "synthetic_detection").

'synthetic_detection'

Returns:

Type Description
SyntheticDetectionData

SyntheticDetectionData with paths to generated NPZ files.

Source code in orchard/data_handler/diagnostic/synthetic_detection.py
def create_synthetic_detection_dataset(
    num_classes: int = 4,  # pragma: no mutate
    samples: int = 50,  # pragma: no mutate
    resolution: int = 64,  # pragma: no mutate
    channels: int = 3,  # pragma: no mutate
    name: str = "synthetic_detection",  # pragma: no mutate
) -> SyntheticDetectionData:
    """
    Create a synthetic detection dataset for testing.

    Generates random images with random bounding boxes and saves them
    as NPZ files (images + annotations separately).

    Args:
        num_classes: Number of object categories (default: 4).
        samples: Number of training images (default: 50).
        resolution: Image size in pixels (default: 64).
        channels: Color channels (default: 3).
        name: Dataset identifier (default: "synthetic_detection").

    Returns:
        SyntheticDetectionData with paths to generated NPZ files.
    """
    rng = np.random.default_rng(_SYNTHETIC_SEED)  # pragma: no mutate

    train_imgs, train_boxes, train_labels = _generate_split(
        rng, samples, resolution, channels, num_classes
    )
    # pragma: no mutate start
    val_samples = max(MIN_SPLIT_SAMPLES, samples // 10)
    test_samples = max(MIN_SPLIT_SAMPLES, samples // 10)
    # pragma: no mutate end

    val_imgs, val_boxes, val_labels = _generate_split(
        rng, val_samples, resolution, channels, num_classes
    )
    test_imgs, test_boxes, test_labels = _generate_split(
        rng, test_samples, resolution, channels, num_classes
    )

    # Save images NPZ
    # pragma: no mutate start
    img_file = tempfile.NamedTemporaryFile(suffix=".npz", delete=False, prefix="det_images_")
    # pragma: no mutate end
    img_path = Path(img_file.name)
    img_file.close()
    np.savez(
        img_path,
        train_images=train_imgs,
        val_images=val_imgs,
        test_images=test_imgs,
    )

    # Save annotations NPZ (object arrays for variable-length boxes)
    # pragma: no mutate start
    ann_file = tempfile.NamedTemporaryFile(suffix=".npz", delete=False, prefix="det_annotations_")
    # pragma: no mutate end
    ann_path = Path(ann_file.name)
    ann_file.close()

    def _to_object_array(lst: list[npt.NDArray[Any]]) -> npt.NDArray[Any]:
        arr = np.empty(len(lst), dtype=object)
        for i, v in enumerate(lst):
            arr[i] = v
        return arr

    np.savez(
        ann_path,
        train_boxes=_to_object_array(train_boxes),
        train_labels=_to_object_array(train_labels),
        val_boxes=_to_object_array(val_boxes),
        val_labels=_to_object_array(val_labels),
        test_boxes=_to_object_array(test_boxes),
        test_labels=_to_object_array(test_labels),
    )

    return SyntheticDetectionData(
        image_path=img_path,
        annotation_path=ann_path,
        num_classes=num_classes,
        name=name,
    )