Files
yolov26_3d/tools/feishu_project/run_cncap_case_pipeline.sh
2026-06-24 09:35:46 +08:00

331 lines
11 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
PROJECT_ROOT=$(cd "${SCRIPT_DIR}/../.." && pwd)
CASE_LIST=${CASE_LIST:-"${PROJECT_ROOT}/tools/feishu_project/cncap_case.txt"}
SYNC_ROOT=${SYNC_ROOT:-/data1/dongying/Mono3d/CNCAP/feishu_project}
EXPORT_JSON=${EXPORT_JSON:-"${SYNC_ROOT}/exports/cncap_case_issue_list.json"}
CASE_INDEX_JSON=${CASE_INDEX_JSON:-"${SYNC_ROOT}/exports/cncap_case_issue_index.json"}
DOWNLOAD_ROOT=${DOWNLOAD_ROOT:-"${SYNC_ROOT}/downloaded_issue_data"}
DOWNLOAD_MANIFEST_PATH=${DOWNLOAD_MANIFEST_PATH:-"${DOWNLOAD_ROOT}/download_manifest.json"}
INFERENCE_ROOT=${INFERENCE_ROOT:-"${SYNC_ROOT}/inference_issue_data"}
INFERENCE_MANIFEST_PATH=${INFERENCE_MANIFEST_PATH:-"${INFERENCE_ROOT}/inference_manifest.json"}
PYTHON_BIN=${PYTHON_BIN:-/deeplearning_team/ydong/dongying/miniconda/envs/dev/bin/python}
RUN_BUILD=${RUN_BUILD:-1}
RUN_DOWNLOAD=${RUN_DOWNLOAD:-1}
RUN_INFERENCE=${RUN_INFERENCE:-1}
ENABLE_TRACKING=${ENABLE_TRACKING:-1}
ENABLE_CONVERT=${ENABLE_CONVERT:-1}
ENABLE_VISUALIZE=${ENABLE_VISUALIZE:-0}
ENABLE_TEMPORAL_ANALYSIS=${ENABLE_TEMPORAL_ANALYSIS:-0}
SKIP_EXISTING_INFERENCE=${SKIP_EXISTING_INFERENCE:-1}
DRY_RUN=${DRY_RUN:-0}
USE_ISSUE_FRAME_WINDOW=${USE_ISSUE_FRAME_WINDOW:-0}
FRAME_BEFORE=${FRAME_BEFORE:-200}
FRAME_AFTER=${FRAME_AFTER:-200}
MISSING_ISSUE_FRAME_POLICY=${MISSING_ISSUE_FRAME_POLICY:-full}
FRAME_INDEX_START=${FRAME_INDEX_START:-}
FRAME_INDEX_END=${FRAME_INDEX_END:-}
FRAME_ID_START=${FRAME_ID_START:-}
FRAME_ID_END=${FRAME_ID_END:-}
TARGET_FRAME_ID=${TARGET_FRAME_ID:-}
VIDEO_STRIDE=${VIDEO_STRIDE:-1}
MAX_IMAGES=${MAX_IMAGES:-0}
EXPORTED_MODEL=${EXPORTED_MODEL:-${PROJECT_ROOT}/runs/export/train_mono3d_two_roi_20260416-raw_no_edge/merged_model.torchscript}
DEVICE=${DEVICE:-}
PROVIDERS=${PROVIDERS:-}
ENABLE_ATTR=${ENABLE_ATTR:-0}
ENABLE_CROSS_CLASS_MERGE_PRIOR=${ENABLE_CROSS_CLASS_MERGE_PRIOR:-1}
SAVE_AGGREGATE_PREDICTIONS=${SAVE_AGGREGATE_PREDICTIONS:-1}
INFERENCE_EXTRA_ARGS=${INFERENCE_EXTRA_ARGS:-}
TRACK_CLASSES=${TRACK_CLASSES:-0 1 2 3 4 5 6 7 8 9 10 11 12}
IOU_THRESH=${IOU_THRESH:-0.3}
MAX_AGE=${MAX_AGE:-5}
MIN_HITS=${MIN_HITS:-1}
DIST_THRESH=${DIST_THRESH:-100}
MAX_3D_DISTANCE=${MAX_3D_DISTANCE:-10.0}
MAX_FRAMES=${MAX_FRAMES:-}
MERGE_OUTPUT_NAME=${MERGE_OUTPUT_NAME:-combined_tracking.json}
FILE_PATTERN=${FILE_PATTERN:-*.json}
ENABLE_USE_3D=${ENABLE_USE_3D:-0}
CONVERT_OUTPUT_DIR_NAME=${CONVERT_OUTPUT_DIR_NAME:-objectlist}
CONVERT_TRACKING_JSON_NAME=${CONVERT_TRACKING_JSON_NAME:-merge.json}
CONVERT_CAM_ID=${CONVERT_CAM_ID:-}
VIS_DOWNLOAD_ROOT=${VIS_DOWNLOAD_ROOT:-"${DOWNLOAD_ROOT}"}
VIS_OUTPUT_ROOT=${VIS_OUTPUT_ROOT:-}
VIS_OUTPUT_DIR_NAME=${VIS_OUTPUT_DIR_NAME:-tracking_vis_raw}
VIS_TRACKING_JSON_NAME=${VIS_TRACKING_JSON_NAME:-merge.json}
VIS_MAX_FRAMES=${VIS_MAX_FRAMES:-}
VIS_CLASS_ID=${VIS_CLASS_ID:-}
VIS_TRACK_IDS=${VIS_TRACK_IDS:-}
VIS_SHOW_TRAJECTORY=${VIS_SHOW_TRAJECTORY:-0}
TEMPORAL_OUTPUT_ROOT=${TEMPORAL_OUTPUT_ROOT:-}
TEMPORAL_OUTPUT_DIR_NAME=${TEMPORAL_OUTPUT_DIR_NAME:-temporal_observation}
TEMPORAL_JSON_NAME=${TEMPORAL_JSON_NAME:-merge.json}
TEMPORAL_MIN_LENGTH=${TEMPORAL_MIN_LENGTH:-3}
TEMPORAL_TRACK_IDS=${TEMPORAL_TRACK_IDS:-}
TEMPORAL_CLASS_ID=${TEMPORAL_CLASS_ID:-}
TEMPORAL_FRAME_ID_START=${TEMPORAL_FRAME_ID_START:-}
TEMPORAL_FRAME_ID_END=${TEMPORAL_FRAME_ID_END:-}
TEMPORAL_PLOTS=${TEMPORAL_PLOTS:-0}
TEMPORAL_EXPORT_SERIES=${TEMPORAL_EXPORT_SERIES:-1}
TEMPORAL_FOCUS_TRACK_PLOTS=${TEMPORAL_FOCUS_TRACK_PLOTS:-1}
TEMPORAL_PREFER_EGO=${TEMPORAL_PREFER_EGO:-1}
TEMPORAL_X_AXIS=${TEMPORAL_X_AXIS:-frame_id}
TEMPORAL_HEADING_SOURCE=${TEMPORAL_HEADING_SOURCE:-camera_reg}
TRACKING_MODEL_VERSION=${TRACKING_MODEL_VERSION:-}
SKIP_MDI=${SKIP_MDI:-0}
SKIP_COPY=${SKIP_COPY:-0}
ONLY_REDOWNLOAD_AFFECTED_CASES=${ONLY_REDOWNLOAD_AFFECTED_CASES:-0}
ID_BASE=${ID_BASE:-9000000000}
CASE_JSON_BUILDER=${CASE_JSON_BUILDER:-"${PROJECT_ROOT}/tools/feishu_project/build_cncap_case_issue_json.py"}
DOWNLOAD_WRAPPER=${DOWNLOAD_WRAPPER:-"${PROJECT_ROOT}/tools/feishu_project/download_issue_data.sh"}
INFERENCE_WRAPPER=${INFERENCE_WRAPPER:-"${PROJECT_ROOT}/tools/feishu_project/run_issue_data_inference.sh"}
TRACKING_WRAPPER=${TRACKING_WRAPPER:-"${PROJECT_ROOT}/tools/feishu_project/run_issue_data_tracking.sh"}
ISSUE_ID_ARGS=()
ISSUE_ID_VALUES=()
show_usage() {
cat <<EOF
Usage:
bash $(basename "${BASH_SOURCE[0]}") [--issue-id <id>]...
Environment variables:
CASE_LIST, SYNC_ROOT, EXPORT_JSON, CASE_INDEX_JSON
DOWNLOAD_ROOT, INFERENCE_ROOT, EXPORTED_MODEL
RUN_BUILD, RUN_DOWNLOAD, RUN_INFERENCE, ENABLE_TRACKING
ENABLE_CONVERT, ENABLE_VISUALIZE, ENABLE_TEMPORAL_ANALYSIS
DRY_RUN, ID_BASE
EOF
}
while (($# > 0)); do
case "$1" in
--issue-id)
if (($# < 2)); then
echo "Error: --issue-id requires a value" >&2
exit 1
fi
ISSUE_ID_ARGS+=("$1" "$2")
ISSUE_ID_VALUES+=("$2")
shift 2
;;
--issue-id=*)
issue_id="${1#*=}"
ISSUE_ID_ARGS+=("$1")
ISSUE_ID_VALUES+=("${issue_id}")
shift
;;
-h|--help)
show_usage
exit 0
;;
*)
echo "Error: unsupported option: $1" >&2
show_usage >&2
exit 1
;;
esac
done
print_stage() {
local stage_name="$1"
echo ""
echo "######################################################################"
echo "# ${stage_name}"
echo "######################################################################"
}
resolve_tracking_model_version() {
if [[ -n "${TRACKING_MODEL_VERSION}" ]]; then
printf '%s\n' "${TRACKING_MODEL_VERSION}"
return 0
fi
if [[ -n "${EXPORTED_MODEL}" ]] && [[ "${EXPORTED_MODEL}" =~ ([0-9]{8}) ]]; then
printf '%s\n' "${BASH_REMATCH[1]}"
return 0
fi
return 1
}
has_local_video_cases() {
local search_root="$1"
shift || true
if [[ ! -d "${search_root}" ]]; then
return 1
fi
if [[ "$#" -eq 0 ]]; then
[[ -n "$(find "${search_root}" -type f -path '*/sigmastar.1/camera4.bin' -print -quit)" ]]
return
fi
local issue_id=""
for issue_id in "$@"; do
if [[ -d "${search_root}/issue_${issue_id}" ]] && [[ -n "$(find "${search_root}/issue_${issue_id}" -type f -path '*/sigmastar.1/camera4.bin' -print -quit)" ]]; then
return 0
fi
done
return 1
}
TMP_ROOT=""
EFFECTIVE_EXPORT_JSON="${EXPORT_JSON}"
EFFECTIVE_CASE_INDEX_JSON="${CASE_INDEX_JSON}"
cleanup() {
if [[ -n "${TMP_ROOT}" && -d "${TMP_ROOT}" ]]; then
rm -rf "${TMP_ROOT}"
fi
}
trap cleanup EXIT
if [[ "${DRY_RUN}" == "1" && "${RUN_BUILD}" == "1" ]]; then
TMP_ROOT=$(mktemp -d /tmp/cncap_case_pipeline.XXXXXX)
EFFECTIVE_EXPORT_JSON="${TMP_ROOT}/cncap_case_issue_list.json"
EFFECTIVE_CASE_INDEX_JSON="${TMP_ROOT}/cncap_case_issue_index.json"
fi
export PYTHON_BIN
export TRACK_CLASSES
export IOU_THRESH
export MAX_AGE
export MIN_HITS
export DIST_THRESH
export MAX_3D_DISTANCE
export MAX_FRAMES
export MERGE_OUTPUT_NAME
export FILE_PATTERN
export ENABLE_USE_3D
export ENABLE_CONVERT
export ENABLE_VISUALIZE
export ENABLE_TEMPORAL_ANALYSIS
export CONVERT_OUTPUT_DIR_NAME
export CONVERT_TRACKING_JSON_NAME
export CONVERT_CAM_ID
export VIS_DOWNLOAD_ROOT
export VIS_OUTPUT_ROOT
export VIS_OUTPUT_DIR_NAME
export VIS_TRACKING_JSON_NAME
export VIS_MAX_FRAMES
export VIS_CLASS_ID
export VIS_TRACK_IDS
export VIS_SHOW_TRAJECTORY
export TEMPORAL_OUTPUT_ROOT
export TEMPORAL_OUTPUT_DIR_NAME
export TEMPORAL_JSON_NAME
export TEMPORAL_MIN_LENGTH
export TEMPORAL_TRACK_IDS
export TEMPORAL_CLASS_ID
export TEMPORAL_FRAME_ID_START
export TEMPORAL_FRAME_ID_END
export TEMPORAL_PLOTS
export TEMPORAL_EXPORT_SERIES
export TEMPORAL_FOCUS_TRACK_PLOTS
export TEMPORAL_PREFER_EGO
export TEMPORAL_X_AXIS
export TEMPORAL_HEADING_SOURCE
if [[ "${RUN_BUILD}" == "1" ]]; then
print_stage "Build CNCAP Synthetic Issue JSON"
echo "CASE_LIST : ${CASE_LIST}"
echo "EXPORT_JSON : ${EFFECTIVE_EXPORT_JSON}"
echo "CASE_INDEX_JSON : ${EFFECTIVE_CASE_INDEX_JSON}"
echo "ID_BASE : ${ID_BASE}"
"${PYTHON_BIN}" "${CASE_JSON_BUILDER}" \
--input "${CASE_LIST}" \
--output "${EFFECTIVE_EXPORT_JSON}" \
--case-index-output "${EFFECTIVE_CASE_INDEX_JSON}" \
--id-base "${ID_BASE}"
elif [[ ! -f "${EFFECTIVE_EXPORT_JSON}" ]]; then
echo "Error: export json does not exist and RUN_BUILD=0: ${EFFECTIVE_EXPORT_JSON}" >&2
exit 1
fi
if [[ "${RUN_DOWNLOAD}" == "1" ]]; then
print_stage "Download CNCAP Case Data"
INPUT_JSON="${EFFECTIVE_EXPORT_JSON}" \
OUTPUT_ROOT="${DOWNLOAD_ROOT}" \
MANIFEST_PATH="${DOWNLOAD_MANIFEST_PATH}" \
PYTHON_BIN="${PYTHON_BIN}" \
DRY_RUN="${DRY_RUN}" \
SKIP_MDI="${SKIP_MDI}" \
SKIP_COPY="${SKIP_COPY}" \
ONLY_REDOWNLOAD_AFFECTED_CASES="${ONLY_REDOWNLOAD_AFFECTED_CASES}" \
bash "${DOWNLOAD_WRAPPER}" "${ISSUE_ID_ARGS[@]}"
fi
if [[ "${RUN_INFERENCE}" == "1" ]]; then
if [[ "${DRY_RUN}" == "1" ]] && ! has_local_video_cases "${DOWNLOAD_ROOT}" "${ISSUE_ID_VALUES[@]}"; then
print_stage "Skip CNCAP Inference"
echo "Skipping inference in dry-run because no local downloaded camera4.bin cases were found."
echo "Run download without DRY_RUN first, or reuse an existing DOWNLOAD_ROOT to plan inference."
else
print_stage "Run CNCAP Inference"
DOWNLOAD_ROOT="${DOWNLOAD_ROOT}" \
OUTPUT_ROOT="${INFERENCE_ROOT}" \
MANIFEST_PATH="${INFERENCE_MANIFEST_PATH}" \
PYTHON_BIN="${PYTHON_BIN}" \
ISSUE_JSON="${EFFECTIVE_EXPORT_JSON}" \
VIDEO_STRIDE="${VIDEO_STRIDE}" \
MAX_IMAGES="${MAX_IMAGES}" \
FRAME_INDEX_START="${FRAME_INDEX_START}" \
FRAME_INDEX_END="${FRAME_INDEX_END}" \
FRAME_ID_START="${FRAME_ID_START}" \
FRAME_ID_END="${FRAME_ID_END}" \
TARGET_FRAME_ID="${TARGET_FRAME_ID}" \
FRAME_BEFORE="${FRAME_BEFORE}" \
FRAME_AFTER="${FRAME_AFTER}" \
USE_ISSUE_FRAME_WINDOW="${USE_ISSUE_FRAME_WINDOW}" \
MISSING_ISSUE_FRAME_POLICY="${MISSING_ISSUE_FRAME_POLICY}" \
EXPORTED_MODEL="${EXPORTED_MODEL}" \
DEVICE="${DEVICE}" \
PROVIDERS="${PROVIDERS}" \
ENABLE_ATTR="${ENABLE_ATTR}" \
ENABLE_CROSS_CLASS_MERGE_PRIOR="${ENABLE_CROSS_CLASS_MERGE_PRIOR}" \
SAVE_AGGREGATE_PREDICTIONS="${SAVE_AGGREGATE_PREDICTIONS}" \
SKIP_EXISTING="${SKIP_EXISTING_INFERENCE}" \
DRY_RUN="${DRY_RUN}" \
ENABLE_TRACKING=0 \
INFERENCE_EXTRA_ARGS="${INFERENCE_EXTRA_ARGS}" \
bash "${INFERENCE_WRAPPER}" "${ISSUE_ID_ARGS[@]}"
fi
fi
if [[ "${ENABLE_TRACKING}" != "1" ]]; then
exit 0
fi
if [[ "${DRY_RUN}" == "1" ]]; then
print_stage "Skip CNCAP Tracking"
echo "Skipping tracking because DRY_RUN=1."
exit 0
fi
TRACKING_MODEL_VERSION_RESOLVED=$(resolve_tracking_model_version || true)
print_stage "Run CNCAP Tracking/Convert Workflow"
echo "INFERENCE_ROOT : ${INFERENCE_ROOT}"
echo "VIS_DOWNLOAD_ROOT : ${VIS_DOWNLOAD_ROOT}"
if [[ -n "${TRACKING_MODEL_VERSION_RESOLVED}" ]]; then
echo "TRACKING_MODEL_VERSION : ${TRACKING_MODEL_VERSION_RESOLVED}"
fi
RESULTS_ROOT="${INFERENCE_ROOT}" \
PYTHON_BIN="${PYTHON_BIN}" \
TRACKING_MODEL_VERSION="${TRACKING_MODEL_VERSION_RESOLVED}" \
bash "${TRACKING_WRAPPER}" "${INFERENCE_ROOT}" "${ISSUE_ID_ARGS[@]}"