This folder contains an offline OpenCV/NumPy script for estimating the number of shipping containers in an aerial image and marking detections in sequential groups.
For the complete reference-image, yellow-dot annotation, YOLO training, and validation workflow, see docs/image-to-model-walkthrough.md.
C:/Python314/python.exe -m pip install -r requirements.txtC:/Python314/python.exe count_containers.py `
--input 2005-0120_01.jpg `
--output annotated_2005-0120_01.jpg `
--debug-dir debugThe default group size is 25. Change it with --group-size 25. The command prints the estimated total and writes an annotated image with colored outlines and a G1, G2, and so on marker for each group.
The detector is intentionally explainable rather than model-based. For a differently framed image, adjust the normalized region of interest and shape bounds, for example:
C:/Python314/python.exe count_containers.py `
--input another-image.jpg `
--output another-image-annotated.jpg `
--roi 0,0.16,1,0.78 `
--min-area 75 `
--max-area 2000 `
--max-aspect-ratio 5--roi uses normalized x,y,width,height values. Use --debug-dir to save the edge mask used for candidate generation. Review the outlines before treating the printed number as final: aerial imagery can contain roads, equipment, stacked containers, and other rectangular structures that require threshold tuning or manual correction.
For better accuracy, create ground-truth labels from the supplied image before training a model. Start the local annotator:
C:/Python314/python.exe label_containers.py `
--image 2005-0120_01.jpg `
--dataset-root datasetThe browser page supports drawing, selecting, deleting, undoing, zooming, panning, and exporting a review image. Draw one box around each visible container, including partially visible containers at the image edge. Use Zoom +, then hold Space and drag the image to pan; middle-mouse drag also pans. Save periodically.
Saving creates:
dataset/images/train/2005-0120_01.jpgdataset/labels/train/2005-0120_01.txtin YOLO formatdataset/annotations/2005-0120_01.jsonfor editable pixel-coordinate boxesdataset/data.yamlwith one class namedcontainer
Do not use the current OpenCV output as labels; its false positives would teach the model the wrong class. After this image is labeled, add several similar images and split them into training and validation examples before fine-tuning a detector.
If an annotation image contains one yellow dot at each container center, generate provisional boxes with:
C:/Python314/python.exe generate_point_labels.py `
--image 2005-0120_01.jpg `
--annotation 2025-0120_2125.png `
--dataset-root dataset `
--review-output provisional_2005-0120_01.jpgThe clean image is copied into the dataset, while the yellow-dot image is used only to create center-derived provisional boxes. Review provisional_2005-0120_01.jpg and correct the boxes in the labeling page before training; these boxes are not exact ground truth.
C:/Python314/python.exe -m unittest discover -v