HumansXドキュメントセンター 公式サイトへ ↗

主要機能の紹介

概要

インテリジェント顔追跡システムは、先進的なコンピュータービジョン技術と精密な雲台制御アルゴリズムを統合し、顔検出から自動追跡までを一貫して行うシステムを実現しています。YOLO11ディープラーニングモデルと各種インテリジェントアルゴリズムに基づき、高精度・低遅延のリアルタイム顔追跡機能を提供します。

🎯 顔検出システム

YOLO11検出エンジン

技術的特長:

  • モデルアーキテクチャ: RDK X5プラットフォーム向けに最適化されたYOLO11n量子化モデル
  • 検出対象: 顔検出専用、複数人の顔が映るシーンに対応
  • 入力サイズ: 320×320ピクセル、NV12形式入力
  • 検出精度: 信頼度しきい値0.6、IoUしきい値0.45(設定可能)
  • 処理速度: 約30fpsのリアルタイム検出、BPUハードウェアアクセラレーション
  • 検出距離: 0.5~5mの範囲の顔検出に対応

検出の流れ:

  1. 画像の前処理: BGR形式からNV12形式に変換し、320×320にリサイズ
  2. モデル推論: Horizon BPU上でハードウェアアクセラレーション推論を実行
  3. 後処理: 非最大値抑制(NMS)、座標の逆量子化
  4. 結果出力: バウンディングボックス座標、信頼度、顔ID情報

主要クラスの設計:

class YOLO11_FaceDetect:
    def __init__(self, model_path, conf_thres=0.6, iou_thres=0.45):
        self.dnn_handle = load_model(model_path)
        self.conf_thres = conf_thres
        self.iou_thres = iou_thres
        self.input_shape = (320, 320)

    def detect(self, frame) -> List[Detection]:
        # 1. 图像预处理
        input_tensor = self.preprocess(frame)

        # 2. BPU推理
        outputs = self.forward(input_tensor)

        # 3. 后处理
        detections = self.postprocess(outputs, frame.shape)

        return detections

    def preprocess(self, frame):
        """BGR转NV12格式预处理"""
        # 缩放到模型输入尺寸
        resized = cv2.resize(frame, self.input_shape)

        # BGR转YUV420(NV12)
        yuv = cv2.cvtColor(resized, cv2.COLOR_BGR2YUV_I420)

        return yuv

    def postprocess(self, outputs, original_shape):
        """后处理:NMS + 坐标还原"""
        # 解析模型输出
        boxes, scores, class_ids = self.decode_output(outputs)

        # 非极大值抑制
        indices = cv2.dnn.NMSBoxes(boxes, scores,
                                   self.conf_thres, self.iou_thres)

        # 坐标还原到原始图像尺寸
        detections = []
        if len(indices) > 0:
            for i in indices.flatten():
                box = self.scale_box(boxes[i], original_shape)
                detections.append(Detection(
                    bbox=box,
                    confidence=scores[i],
                    class_id=class_ids[i]
                ))

        return detections

検出性能の最適化

BPUハードウェアアクセラレーション:

  • Horizon BPUを利用してINT8量子化推論を実行
  • CPU推論と比べて8~10倍高速
  • 消費電力を70%削減し、組み込み用途に最適

メモリ最適化:

  • インプレースの画像処理でメモリコピーを削減
  • リングバッファの再利用で頻繁なメモリ確保を回避
  • インテリジェントなガベージコレクションでメモリのピークを抑制

マルチスレッド最適化:

  • 画像取得と推論を並列処理
  • 非同期の後処理パイプライン
  • ロックの最適化でスレッド競合を削減

🎯 インテリジェント追跡システム

複数対象追跡のアーキテクチャ

システム構成:

检测结果 → 目标关联 → 目标评分 → 目标选择 → 追踪输出
    ↓           ↓         ↓         ↓         ↓
 边界框列表 → ID匹配  → 综合评分 → 最优选择 → 追踪坐标

対象関連付けアルゴリズム

ハンガリアンアルゴリズムによるマッチング:

class TargetAssociator:
    def __init__(self, max_distance=100.0):
        self.max_distance = max_distance
        self.target_history = {}

    def associate_targets(self, current_detections, previous_targets):
        """使用匈牙利算法进行目标关联"""
        if not previous_targets:
            return self.initialize_new_targets(current_detections)

        # 计算距离矩阵
        cost_matrix = self.compute_cost_matrix(
            current_detections, previous_targets
        )

        # 匈牙利算法求解最优匹配
        from scipy.optimize import linear_sum_assignment
        row_indices, col_indices = linear_sum_assignment(cost_matrix)

        # 处理匹配结果
        matched_targets = []
        unmatched_detections = []

        for det_idx, detection in enumerate(current_detections):
            if det_idx in row_indices:
                # 找到匹配的历史目标
                target_idx = col_indices[row_indices == det_idx][0]
                if cost_matrix[det_idx, target_idx] < self.max_distance:
                    # 更新匹配的目标
                    target = previous_targets[target_idx]
                    target.update(detection)
                    matched_targets.append(target)
                else:
                    # 距离太远,创建新目标
                    unmatched_detections.append(detection)
            else:
                unmatched_detections.append(detection)

        # 为未匹配的检测创建新目标
        new_targets = self.create_new_targets(unmatched_detections)

        return matched_targets + new_targets

    def compute_cost_matrix(self, detections, targets):
        """计算检测与目标之间的代价矩阵"""
        matrix = np.zeros((len(detections), len(targets)))

        for i, detection in enumerate(detections):
            det_center = detection.get_center()
            for j, target in enumerate(targets):
                target_center = target.get_predicted_center()

                # 欧氏距离作为基础代价
                distance = np.linalg.norm(det_center - target_center)

                # 考虑置信度差异
                conf_diff = abs(detection.confidence - target.confidence)

                # 综合代价
                matrix[i, j] = distance + conf_diff * 50

        return matrix

対象スコアリングシステム

複数要素スコアリングモデル:

class TargetScorer:
    def __init__(self, weights=None):
        self.weights = weights or {
            'confidence': 0.3,      # 置信度权重
            'size': 0.2,           # 大小权重
            'persistence': 0.25,    # 持久性权重
            'position': 0.15,      # 位置连续性权重
            'current_bonus': 0.1   # 当前目标加成
        }

    def calculate_score(self, target, is_current_target=False):
        """计算目标综合评分"""
        # 1. 基础评分(置信度 + 归一化大小)
        normalized_area = min(target.area / (640 * 480), 1.0)
        base_score = (self.weights['confidence'] * target.confidence +
                     self.weights['size'] * normalized_area)

        # 2. 持久性评分(连续检测次数)
        max_history = 50
        persistence_score = min(target.detection_count / max_history, 1.0)

        # 3. 位置连续性评分
        if hasattr(target, 'position_history') and len(target.position_history) > 1:
            recent_positions = target.position_history[-5:]  # 最近5帧
            distances = []
            for i in range(1, len(recent_positions)):
                dist = np.linalg.norm(
                    np.array(recent_positions[i]) - np.array(recent_positions[i-1])
                )
                distances.append(dist)

            avg_distance = np.mean(distances) if distances else 0
            max_stable_distance = 20  # 像素
            position_score = max(0, 1.0 - avg_distance / max_stable_distance)
        else:
            position_score = 0.5  # 新目标给中等评分

        # 4. 当前目标加成(避免频繁切换)
        current_bonus = self.weights['current_bonus'] if is_current_target else 0

        # 综合评分
        final_score = (base_score +
                      self.weights['persistence'] * persistence_score +
                      self.weights['position'] * position_score +
                      current_bonus)

        return final_score

動き予測システム

カルマンフィルターの実装:

class KalmanTracker:
    def __init__(self):
        self.kf = cv2.KalmanFilter(4, 2)  # 状态维度4,观测维度2
        self.setup_kalman_filter()

    def setup_kalman_filter(self):
        """初始化卡尔曼滤波器参数"""
        dt = 1.0  # 时间步长

        # 状态转移矩阵 F
        self.kf.transitionMatrix = np.array([
            [1, 0, dt, 0],   # x' = x + vx*dt
            [0, 1, 0, dt],   # y' = y + vy*dt
            [0, 0, 1, 0],    # vx' = vx
            [0, 0, 0, 1]     # vy' = vy
        ], dtype=np.float32)

        # 观测矩阵 H
        self.kf.measurementMatrix = np.array([
            [1, 0, 0, 0],    # 观测x
            [0, 1, 0, 0]     # 观测y
        ], dtype=np.float32)

        # 过程噪声协方差矩阵 Q
        self.kf.processNoiseCov = np.eye(4, dtype=np.float32) * 0.1

        # 测量噪声协方差矩阵 R
        self.kf.measurementNoiseCov = np.eye(2, dtype=np.float32) * 1.0

        # 初始状态协方差矩阵 P
        self.kf.errorCovPost = np.eye(4, dtype=np.float32) * 1000

    def predict(self):
        """预测下一时刻状态"""
        prediction = self.kf.predict()
        return prediction[:2]  # 返回位置预测

    def update(self, measurement):
        """使用观测值更新状态"""
        self.kf.correct(np.array(measurement, dtype=np.float32))

    def get_state(self):
        """获取当前状态估计"""
        return self.kf.statePost.flatten()

運動モデルの選択:

  • 等速運動モデル: 安定して移動する対象に適用
  • 等加速度運動モデル: 加速度が変化する対象に適用
  • 旋回モデル: 方向が変化する対象に適用

ブレ防止戦略

対象切替しきい値の仕組み:

class TargetSwitchController:
    def __init__(self, switch_threshold=0.15, min_stable_frames=5):
        self.switch_threshold = switch_threshold
        self.min_stable_frames = min_stable_frames
        self.current_target_id = None
        self.stable_frame_count = 0

    def should_switch_target(self, current_target, best_target):
        """判断是否应该切换追踪目标"""
        if current_target is None:
            return True, best_target

        # 计算评分差值
        score_diff = best_target.score - current_target.score

        # 只有当新目标评分显著高于当前目标时才切换
        if score_diff > self.switch_threshold:
            # 需要连续稳定几帧才切换
            if best_target.id == getattr(self, 'candidate_target_id', None):
                self.stable_frame_count += 1
                if self.stable_frame_count >= self.min_stable_frames:
                    self.stable_frame_count = 0
                    return True, best_target
            else:
                self.candidate_target_id = best_target.id
                self.stable_frame_count = 1

        return False, current_target

🔧 雲台制御システム

ハードウェアインターフェース仕様

通信プロトコル:

  • インターフェース種別: RS232シリアル通信
  • デバイスパス: /dev/ttyS1
  • ボーレート: 115200 bps
  • データビット: 8ビット
  • ストップビット: 1ビット
  • パリティ: なし
  • フロー制御: ハードウェアフロー制御なし

サーボ仕様:

  • 種類: PWMデジタルサーボ
  • 制御精度: 1度刻み
  • 角度範囲: 0°~270°(水平・垂直)
  • 応答速度: 60°/秒(最大)
  • 繰り返し精度: ±0.5°
  • 動作電圧: 6V~7.4V

シリアル通信プロトコル

コマンド形式:

[Header] [Address] [Command] [Data] [Checksum]
  0x55     0xFF      0xXX    N bytes   0xXX

サーボ制御コマンド:

class ServoProtocol:
    def __init__(self, serial_port):
        self.serial = serial_port
        self.header = 0x55
        self.address = 0xFF

    def move_servo(self, servo_id, angle):
        """发送舵机移动命令"""
        # 角度转换为PWM值(500-2500us对应0-180度)
        pwm_value = int(500 + (angle / 270.0) * 2000)

        # 构建命令包
        command = 0x03  # 舵机移动命令
        data = [
            servo_id,           # 舵机ID
            (pwm_value >> 8) & 0xFF,  # PWM高字节
            pwm_value & 0xFF,   # PWM低字节
            0x00, 0x00          # 移动时间(0表示最快)
        ]

        # 计算校验和
        checksum = self.calculate_checksum([command] + data)

        # 发送命令
        packet = [self.header, self.address, command] + data + [checksum]
        self.serial.write(bytes(packet))

    def calculate_checksum(self, data):
        """计算校验和"""
        return (~sum(data)) & 0xFF

    def read_response(self, timeout=1.0):
        """读取舵机响应"""
        start_time = time.time()
        buffer = []

        while time.time() - start_time < timeout:
            if self.serial.in_waiting > 0:
                byte = self.serial.read(1)[0]
                buffer.append(byte)

                # 检查是否收到完整响应包
                if len(buffer) >= 6:  # 最小响应包长度
                    if buffer[0] == 0x55:  # 正确的包头
                        return self.parse_response(buffer)

            time.sleep(0.001)  # 短暂休眠

        raise TimeoutError("舵机响应超时")

PID制御システム

PIDコントローラーの実装:

class PIDController:
    def __init__(self, kp=0.6, ki=0.1, kd=0.05,
                 max_integral=20.0, min_output=-50, max_output=50):
        self.kp = kp  # 比例系数
        self.ki = ki  # 积分系数
        self.kd = kd  # 微分系数

        # 积分限幅
        self.max_integral = max_integral
        self.integral = 0.0

        # 输出限幅
        self.min_output = min_output
        self.max_output = max_output

        # 历史值
        self.previous_error = 0.0
        self.previous_time = time.time()

        # 特殊处理标志
        self.is_first_update = True
        self.first_update_factor = 0.3  # 首次响应衰减因子

    def update(self, error, current_time=None):
        """PID控制器更新"""
        if current_time is None:
            current_time = time.time()

        dt = current_time - self.previous_time
        if dt <= 0:
            dt = 0.01  # 避免除零

        # 比例项
        proportional = self.kp * error

        # 积分项
        self.integral += error * dt
        # 积分限幅(防止积分饱和)
        self.integral = np.clip(self.integral,
                               -self.max_integral, self.max_integral)
        integral_term = self.ki * self.integral

        # 微分项
        derivative = (error - self.previous_error) / dt
        derivative_term = self.kd * derivative

        # PID输出
        output = proportional + integral_term + derivative_term

        # 首次更新特殊处理(减少过冲)
        if self.is_first_update:
            output *= self.first_update_factor
            self.is_first_update = False

        # 输出限幅
        output = np.clip(output, self.min_output, self.max_output)

        # 更新历史值
        self.previous_error = error
        self.previous_time = current_time

        return output

    def reset(self):
        """重置PID控制器状态"""
        self.integral = 0.0
        self.previous_error = 0.0
        self.previous_time = time.time()
        self.is_first_update = True

    def set_gains(self, kp, ki, kd):
        """动态调整PID参数"""
        self.kp = kp
        self.ki = ki
        self.kd = kd

適応型PIDパラメーター調整:

class AdaptivePIDController(PIDController):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.error_history = deque(maxlen=10)
        self.base_kp = self.kp

    def update(self, error, current_time=None):
        self.error_history.append(abs(error))

        # 根据误差大小自适应调整参数
        avg_error = np.mean(self.error_history)

        if avg_error > 100:  # 大误差:增大比例系数,快速响应
            self.kp = self.base_kp * 1.5
            self.ki *= 0.8  # 减小积分,避免超调
        elif avg_error < 20:  # 小误差:减小比例系数,提高稳定性
            self.kp = self.base_kp * 0.7
            self.ki *= 1.2  # 增大积分,消除静差
        else:
            self.kp = self.base_kp  # 恢复默认参数

        return super().update(error, current_time)

雲台の運動学

座標系の変換:

class GimbalKinematics:
    def __init__(self, image_center=(320, 240), fov_h=60, fov_v=45):
        self.image_center = image_center
        self.fov_h = math.radians(fov_h)  # 水平视场角
        self.fov_v = math.radians(fov_v)  # 垂直视场角

    def pixel_to_angle(self, pixel_x, pixel_y, image_width=640, image_height=480):
        """像素坐标转换为云台角度偏移"""
        # 计算相对于图像中心的像素偏移
        pixel_offset_x = pixel_x - self.image_center[0]
        pixel_offset_y = pixel_y - self.image_center[1]

        # 归一化到[-1, 1]范围
        norm_x = pixel_offset_x / (image_width / 2)
        norm_y = pixel_offset_y / (image_height / 2)

        # 转换为角度(弧度)
        angle_x = norm_x * (self.fov_h / 2)
        angle_y = norm_y * (self.fov_v / 2)

        # 转换为度
        return math.degrees(angle_x), math.degrees(angle_y)

    def angle_to_servo_position(self, angle_offset_x, angle_offset_y,
                               current_pan=135, current_tilt=135):
        """角度偏移转换为舵机绝对位置"""
        # 计算新的舵机位置
        new_pan = current_pan + angle_offset_x
        new_tilt = current_tilt - angle_offset_y  # 注意Y轴方向相反

        # 角度限制
        new_pan = np.clip(new_pan, 0, 270)
        new_tilt = np.clip(new_tilt, 0, 270)

        return new_pan, new_tilt

📊 システム統合とデータフロー

リアルタイム処理パイプライン

データフローのアーキテクチャ:

摄像头捕获 → 图像预处理 → 人脸检测 → 目标追踪 → 运动预测 → PID控制 → 云台执行
     ↓            ↓           ↓         ↓         ↓         ↓         ↓
  30fps BGR   →  NV12格式  → YOLO11  → 匈牙利算法 → 卡尔曼滤波 → PID输出 → 串口通信
    |            |           |         |         |         |         |
    |            |           |         |         |         |         ↓
    |            |           |         |         |         |      舵机响应
    |            |           |         |         |         |
    ↓            ↓           ↓         ↓         ↓         ↓
  Web视频流  ← 结果绘制  ← 检测框绘制 ← 目标标记 ← 轨迹预测 ← 控制反馈

性能最適化戦略:

  1. 並列処理: 検出と制御を非同期で実行
  2. キャッシュ最適化: インテリジェントなキャッシュ戦略で計算量を削減
  3. メモリ管理: オブジェクトプールの再利用でGCを削減
  4. ハードウェアアクセラレーション: BPUとGPUのリソースを最大限に活用

マルチスレッドの協調

import threading
import queue
from concurrent.futures import ThreadPoolExecutor

class FaceTrackingSystem:
    def __init__(self):
        self.detection_queue = queue.Queue(maxsize=5)
        self.control_queue = queue.Queue(maxsize=10)
        self.running = False
        self.executor = ThreadPoolExecutor(max_workers=3)

    def start(self):
        """启动多线程追踪系统"""
        self.running = True

        # 启动各个工作线程
        self.detection_thread = threading.Thread(
            target=self._detection_worker, daemon=True
        )
        self.tracking_thread = threading.Thread(
            target=self._tracking_worker, daemon=True
        )
        self.control_thread = threading.Thread(
            target=self._control_worker, daemon=True
        )

        self.detection_thread.start()
        self.tracking_thread.start()
        self.control_thread.start()

    def _detection_worker(self):
        """人脸检测工作线程"""
        while self.running:
            frame = self.camera.read()
            if frame is not None:
                # 提交检测任务到线程池
                future = self.executor.submit(self.detector.detect, frame)
                try:
                    detections = future.result(timeout=0.1)  # 100ms超时
                    self.detection_queue.put((frame, detections), block=False)
                except (queue.Full, TimeoutError):
                    # 队列满或检测超时,跳过当前帧
                    pass

    def _tracking_worker(self):
        """目标追踪工作线程"""
        while self.running:
            try:
                frame, detections = self.detection_queue.get(timeout=1.0)

                # 执行追踪算法
                tracking_result = self.tracker.update(detections)

                if tracking_result.has_valid_target:
                    # 计算控制指令
                    control_cmd = self.calculate_control_command(
                        tracking_result.target_center
                    )
                    self.control_queue.put(control_cmd, block=False)

                self.detection_queue.task_done()

            except queue.Empty:
                continue
            except queue.Full:
                # 控制队列满,跳过当前控制指令
                pass

    def _control_worker(self):
        """云台控制工作线程"""
        while self.running:
            try:
                control_cmd = self.control_queue.get(timeout=1.0)

                # 执行云台控制
                self.gimbal_controller.execute_command(control_cmd)

                self.control_queue.task_done()

            except queue.Empty:
                continue

    def stop(self):
        """停止追踪系统"""
        self.running = False

        # 等待所有线程结束
        self.detection_thread.join(timeout=2.0)
        self.tracking_thread.join(timeout=2.0)
        self.control_thread.join(timeout=2.0)

        # 关闭线程池
        self.executor.shutdown(wait=True)

🎨 ユーザーインターフェースと可視化

Webインターフェースの機能

リアルタイム映像ストリーム:

  • MJPEG形式の映像ストリームで低遅延伝送
  • 顔検出枠のリアルタイム描画
  • 追跡対象の特別表示(オレンジ色の枠+ラベル)
  • フレームレートと性能指標の表示

インタラクティブ操作パネル:

  • 雲台の手動制御(矢印キー/マウス)
  • 追跡パラメーターのリアルタイム調整
  • システム状態の監視
  • ログのリアルタイム表示

可視化要素:

def draw_tracking_visualization(frame, tracking_result):
    """绘制追踪可视化信息"""

    # 绘制所有检测到的人脸
    for detection in tracking_result.all_detections:
        color = (0, 255, 0)  # 绿色:普通检测
        thickness = 2

        # 当前追踪目标用特殊颜色
        if detection.id == tracking_result.current_target_id:
            color = (0, 165, 255)  # 橙色:追踪目标
            thickness = 3

            # 添加追踪标签
            label = f"Tracking ID:{detection.id} ({detection.confidence:.2f})"
            cv2.putText(frame, label,
                       (detection.bbox[0], detection.bbox[1] - 10),
                       cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 2)

        # 绘制边界框
        cv2.rectangle(frame,
                     (detection.bbox[0], detection.bbox[1]),
                     (detection.bbox[2], detection.bbox[3]),
                     color, thickness)

        # 绘制中心点
        center = detection.get_center()
        cv2.circle(frame, center, 5, color, -1)

    # 绘制预测轨迹
    if hasattr(tracking_result, 'predicted_path'):
        for i, point in enumerate(tracking_result.predicted_path):
            alpha = 1.0 - (i * 0.2)  # 渐变透明度
            color = (int(255 * alpha), int(165 * alpha), 0)
            cv2.circle(frame, point, 3, color, -1)

    # 绘制系统信息
    info_lines = [
        f"FPS: {tracking_result.fps:.1f}",
        f"Targets: {len(tracking_result.all_detections)}",
        f"Tracking: {'ON' if tracking_result.is_tracking else 'OFF'}",
        f"Gimbal: {tracking_result.gimbal_position}"
    ]

    for i, line in enumerate(info_lines):
        cv2.putText(frame, line, (10, 30 + i * 25),
                   cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 255), 2)

    return frame

📈 性能監視と最適化

主要性能指標

検出性能:

  • 検出フレームレート: 目標28~30fps
  • 検出遅延: エンドツーエンドで<35ms
  • 検出精度: 信頼度>0.6の検出で正解率>95%
  • 誤検出率: <2%(通常の照明条件下)

追跡性能:

  • 追跡安定性: 対象切替頻度<0.1回/秒
  • 追跡精度: 中心のずれ<10ピクセル(距離2mの場合)
  • 応答遅延: 検出から制御実行まで<50ms

制御性能:

  • 雲台応答: 機械的遅延<100ms
  • 制御精度: ±1°の角度精度
  • 滑らかさ: 目立つブレやオーバーシュートなし

性能監視システム

class PerformanceMonitor:
    def __init__(self):
        self.metrics = {
            'detection_fps': deque(maxlen=100),
            'detection_latency': deque(maxlen=100),
            'tracking_latency': deque(maxlen=100),
            'control_latency': deque(maxlen=100),
            'target_switches': 0,
            'total_frames': 0
        }
        self.start_time = time.time()

    def record_detection(self, latency):
        """记录检测性能"""
        current_time = time.time()
        self.metrics['detection_latency'].append(latency)
        self.metrics['total_frames'] += 1

        # 计算FPS
        if len(self.metrics['detection_fps']) == 0:
            self.last_fps_time = current_time
        elif current_time - self.last_fps_time >= 1.0:
            fps = len(self.metrics['detection_fps'])
            self.metrics['detection_fps'].append(fps)
            self.last_fps_time = current_time

    def get_performance_report(self):
        """生成性能报告"""
        uptime = time.time() - self.start_time

        return {
            'uptime': uptime,
            'total_frames': self.metrics['total_frames'],
            'average_fps': self.metrics['total_frames'] / uptime,
            'detection_latency': {
                'avg': np.mean(self.metrics['detection_latency']) if self.metrics['detection_latency'] else 0,
                'max': np.max(self.metrics['detection_latency']) if self.metrics['detection_latency'] else 0,
                'min': np.min(self.metrics['detection_latency']) if self.metrics['detection_latency'] else 0
            },
            'tracking_stability': {
                'target_switches': self.metrics['target_switches'],
                'switches_per_minute': self.metrics['target_switches'] / (uptime / 60)
            }
        }

🔧 設定とチューニング

システム設定パラメーター

検出設定:

detection:
  model_path: "model/yolo11n_face_detect_bayese_320x320_nv12.bin"
  confidence_threshold: 0.6    # 置信度阈值
  iou_threshold: 0.45         # IoU阈值
  max_detections: 10          # 最大检测数量

  # BPU加速配置
  bpu:
    core_id: 0                # BPU核心ID
    priority: "high"          # 推理优先级
    batch_size: 1            # 批处理大小

追跡設定:

tracking:
  max_targets: 5              # 最大追踪目标数
  target_timeout: 3.0         # 目标超时时间(秒)

  # 评分权重
  scoring:
    confidence_weight: 0.3
    size_weight: 0.2
    persistence_weight: 0.25
    position_weight: 0.15
    current_bonus: 0.1

  # 切换控制
  switch_threshold: 0.15      # 切换阈值
  min_stable_frames: 5        # 最少稳定帧数

  # 卡尔曼滤波
  kalman:
    process_noise: 0.1        # 过程噪声
    measurement_noise: 1.0    # 测量噪声
    prediction_enabled: true   # 启用预测

制御設定:

gimbal:
  serial_port: "/dev/ttyS1"
  baudrate: 115200
  timeout: 1.0

  # 舵机配置
  pan_servo_id: 3
  tilt_servo_id: 4

  # 角度限制
  angle_limits:
    pan: [0, 270]
    tilt: [0, 270]

  # PID参数
  pid:
    kp: 0.6
    ki: 0.1
    kd: 0.05
    max_integral: 20.0
    output_limit: [-50, 50]
    first_update_factor: 0.3

  # 平滑控制
  smooth_control:
    enabled: true
    max_angle_change: 8.0     # 最大单次角度变化
    min_interval: 0.01        # 最小控制间隔

インテリジェント顔追跡システムは、先進的なコンピュータービジョンアルゴリズム、インテリジェント制御システム、最適化されたハードウェアインターフェースを統合することで、高精度・低遅延で安定した信頼性の高い顔追跡機能を実現し、完全なインテリジェント監視ソリューションを提供します。

お問い合わせ

資料のダウンロード・技術サポートについては、HumansX株式会社までお問い合わせください。