fire-and-smoke-detection / export_and_quantize.sh
vagheshpatel's picture
Sync fire-and-smoke-detection from metro-analytics-catalog
da15776 verified
Raw
History Blame Contribute Delete
3.93 kB
#!/usr/bin/env bash
# SPDX-License-Identifier: MIT
# Copyright (C) Intel Corporation
#
# Export a community YOLOv26 fire/smoke detector to OpenVINO IR for the
# fire-and-smoke-detection use case. The model detects the "fire" and
# "smoke" classes.
# Usage: ./export_and_quantize.sh [PRECISION]
# Example: ./export_and_quantize.sh FP16
set -euo pipefail
PRECISION="${1:-FP16}"
PRECISION="$(echo "${PRECISION}" | tr '[:lower:]' '[:upper:]')"
MODEL_NAME="yolov26_fire"
MODEL_URL="https://huggingface.co/SalahALHaismawi/yolov26-fire-detection/resolve/main/best.pt"
# CC0 / Pexels-licensed sample video: "Aerial view of wildfire in forested
# area" by K (Kelly), free to use via Pexels.
VIDEO_URL="https://www.pexels.com/download/video/30937716/"
if [[ "${PRECISION}" != "FP32" && "${PRECISION}" != "FP16" && "${PRECISION}" != "INT8" ]]; then
echo "ERROR: unsupported precision '${PRECISION}'. Choose FP32, FP16, or INT8." >&2
exit 1
fi
echo "--- Installing dependencies ---"
if [[ "${PRECISION}" == "INT8" ]]; then
pip install -qU openvino nncf ultralytics
else
pip install -qU openvino ultralytics
fi
# Ask for approval before downloading models and sample files
echo ""
echo "This script will download:"
echo " - Community YOLOv26 fire/smoke model weights"
echo " - A Pexels-licensed sample wildfire video"
echo ""
read -p "Continue with downloads? (yes/no): " APPROVAL
if [[ "${APPROVAL}" != "yes" ]]; then
echo "Download cancelled by user."
exit 0
fi
echo ""
echo "--- Downloading fire/smoke model weights ---"
if [[ ! -f "${MODEL_NAME}.pt" ]]; then
curl -sL -o "${MODEL_NAME}.pt" "${MODEL_URL}"
echo "Downloaded: ${MODEL_NAME}.pt"
else
echo "Already present: ${MODEL_NAME}.pt"
fi
echo "--- Downloading and transcoding sample test video ---"
# Both samples run on an H.264 MP4. A fire/smoke-rich 8-second window is
# trimmed, center-cropped to a square (so the fixed 640x640 resize does not
# distort the aspect ratio the model is sensitive to), and transcoded with
# ffmpeg.
if [[ ! -f test_video.mp4 ]]; then
if ! command -v ffmpeg >/dev/null 2>&1; then
echo "ERROR: ffmpeg is required to transcode the sample video." >&2
echo "Install it (e.g. 'sudo apt-get install ffmpeg') and re-run." >&2
exit 1
fi
curl -sL -o fire_source.mp4 "${VIDEO_URL}"
ffmpeg -y -loglevel error -ss 2 -t 8 -i fire_source.mp4 \
-vf "crop=ih:ih,scale=736:736,format=yuv420p" \
-c:v libx264 -preset veryfast -an test_video.mp4
rm -f fire_source.mp4
echo "Downloaded and transcoded: test_video.mp4"
else
echo "Already present: test_video.mp4"
fi
if [[ "${PRECISION}" == "FP32" ]]; then
HALF_FLAG="False"
EXPORT_LABEL="FP32"
else
HALF_FLAG="True"
EXPORT_LABEL="FP16"
fi
echo "--- Exporting ${MODEL_NAME} to OpenVINO IR (${EXPORT_LABEL}) ---"
python3 -c "
from ultralytics import YOLO
model = YOLO('${MODEL_NAME}.pt')
model.export(format='openvino', half=${HALF_FLAG}, dynamic=False, imgsz=640)
print('Export complete: ${MODEL_NAME}_openvino_model/')
"
if [[ "${PRECISION}" == "INT8" ]]; then
echo "--- Quantizing to INT8 with NNCF ---"
python3 -c "
import nncf
import openvino as ov
import numpy as np
import cv2
core = ov.Core()
model = core.read_model('${MODEL_NAME}_openvino_model/${MODEL_NAME}.xml')
cap = cv2.VideoCapture('test_video.mp4')
ok, frame = cap.read()
cap.release()
img = cv2.resize(frame, (640, 640))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB).astype(np.float32) / 255.0
img = img.transpose(2, 0, 1)[np.newaxis, ...]
def transform_fn(data_item):
return img
calibration_dataset = nncf.Dataset(list(range(300)), transform_fn)
quantized = nncf.quantize(
model,
calibration_dataset,
preset=nncf.QuantizationPreset.MIXED,
subset_size=300,
)
ov.save_model(quantized, '${MODEL_NAME}_int8.xml')
print('Quantization complete: ${MODEL_NAME}_int8.xml')
"
fi
echo "--- Done ---"