A production-oriented computer vision pipeline for estimating broiler chicken weight from video streams. The system is designed for real-world poultry houses, emphasizing robustness, interpretability, and low computational cost.
Unlike deep-learning–heavy solutions, this project focuses on classical CV and geometric modeling, making it suitable for edge deployment, rapid prototyping, and environments with limited labeled data.
Sample.mp4
- Enables non-contact weight monitoring in poultry farms.
- Reduces reliance on manual weighing.
- Designed for continuous, camera-based operation.
- Prioritizes explainability and engineering simplicity.
- Relevant Domains: AgTech & Precision Livestock · Edge / Applied Computer Vision.
- End-to-End Video Pipeline: Frame ingestion, ROI handling, segmentation, object validation, and weight estimation.
- Classical, Learning-Free Segmentation: HSV-based foreground extraction with morphological refinement.
- Robust Object Selection: Overlap rejection, boundary-touching instance removal, confidence scoring, and configurable Top-K candidate selection.
- Pose-Normalized, Density-Aware Weight Estimation: Orientation normalization + geometry-based volume computation, converted to weight using configurable broiler density (default: 900 kg/m³).
- Structured Outputs: CSV logging and annotated video output for debugging and offline analysis.
- Modular Architecture: Strategy and Factory patterns enabling extensibility and future DL integration.
├── src
├── main execution.py # Main entry point
├── VideoProcessorPipeline.py # Core video processing pipeline
├── CameraLoader.py # Camera configuration loader
├── SegmentationStrategy.py # Segmentation implementations (Classical/Deep Learning)
├── ObjectFilterStrategy.py # Object filtering and scoring logic
├── AreaCalculatorStrategy.py # Volume/weight calculation strategies
├── OutputWriters.py # Output formatters (CSV)
├── Factories.py # Factory classes for strategy creation
├── VideoIOClass.py # Video input/output utilities
├── cameras_config.json # Camera configuration file
├── broiler_template.png # Template mask for broiler matching
└── cam1.mp4 # Sample video file
├── requirements.txt
└── README.md
- Python 3.7+
- OpenCV 4.x
- NumPy
pip install opencv-python numpyThe system is configured via cameras_config.json. Each camera entry defines:
crop: Region of interest coordinates (x1, y1, x2, y2).feeder: Feeder area coordinates (for calibration).pixet_to_cm: Pixel-to-centimeter calibration factor.
Example configuration:
{
"cameras": {
"cam1": {
"crop": {"x1": 1900, "y1": 590, "x2": 3180, "y2": 1475},
"feeder": {"x1": 1700, "y1": 700, "x2": 2250, "y2": 1100},
"pixet_to_cm": 0.09
}
}
}- Accurate weight estimation requires pixel-to-real-world calibration (pixel_to_cm in
cameras_config.jsonfile). - In this project, the Segment Anything Model (SAM) is used to segment the feeder region from the image, producing a clean, reliable mask of a known reference object.
- In the current implementation, the pixel-to-centimeter conversion factor is set manually based on the segmented feeder dimensions.
- In commercial farm environments, feeders are well-suited for calibration because their geometry and physical dimensions are typically fixed and known. This makes feeder-based calibration a practical, repeatable approach that does not require additional calibration targets.
Volume estimation is performed by slicing the segmented broiler mask into vertical cross-sections, each approximated as a cylinder with height proportional to the pixel resolution.
- Configure camera parameters in
cameras_config.json. - Place input video files in the project directory.
- (Optional) Adjust the Top-K candidate selection via the
top_kparameter in the object filtering stage. - Update the video path in
main_execution.pyif needed. - Run the main script:
python "main execution.py"The system processes the input video and saves an annotated output video along with a camera-specific CSV file named <camera_id>_results.csv.
The CSV output contains the following columns:
| Field | Description |
|---|---|
camera_id |
Camera identifier |
frame_idx |
Frame number |
label |
Object label (default: "broiler") |
score |
Combined confidence score |
volume |
Estimated weight (kg) |
crop_region |
Bounding box coordinates (x, y, w, h) |
These are deliberate design choices aimed at reliability, transparency, and low deployment cost.
- Simplified Body Model: Weight estimation is based on a cylindrical body assumption to ensure computational efficiency and interpretability.
- Lighting Sensitivity: Classical segmentation performs best under controlled illumination, which is a common constraint in commercial poultry houses.
- Manual Calibration: Pixel-to-centimeter calibration is currently configured on a per-camera basis to maintain measurement accuracy.
- Template Dependency: Shape-based validation relies on orientation-consistent templates, prioritizing precision over recall.
- Continuous per-frame estimation is often unnecessary; sampling frames and top-ranked broilers within a fixed time window can reduce computation without sacrificing monitoring quality.
A Docker image is provided for this project to demonstrate an end-to-end inference pipeline.
Currently, the container runs using an internal sample video for reproducibility and quick testing.
Support for external input videos (via mounted volumes and CLI arguments) will be added in a future update.
You can download and run the image from Docker Hub:
docker pull anasiri63/broiler-weight-inference:0.0.1- Integration of deep learning models for improved segmentation.
- Posture-aware frame selection to improve volume-based weight estimation accuracy.
- Multi-species support with configurable templates.
- Web interface for configuration and monitoring.
- Statistical analysis and reporting features.
MIT License.
Contributions are welcome! Please feel free to submit a Pull Request.