You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于React Native实现摄像头帧内宠物识别及离开告警需求问询

React Native Vision Camera 实现宠物移出指定框体告警

核心思路

要实现宠物移出框体告警,关键是在每一帧中获取宠物的检测坐标,与自定义框的坐标做碰撞判断,当检测到宠物完全/部分移出框体时触发告警。

步骤实现

1. 配置帧处理器与目标检测

先确保通过react-native-vision-camera的Frame Processor集成宠物检测模型(比如MLKit物体检测、TensorFlow Lite宠物识别模型),在每一帧中获取宠物的bounding box数据(包含x, y, width, height,基于摄像头帧坐标系)。

示例帧处理器代码:

import { useFrameProcessor } from 'react-native-vision-camera';
import { runPetDetection } from './your-pet-detector'; // 你的宠物检测逻辑

const frameProcessor = useFrameProcessor((frame) => {
  'worklet';
  const detections = runPetDetection(frame); // 得到宠物检测结果数组
  // 后续处理检测结果
}, []);

2. 映射UI框体到摄像头帧坐标系

UI上的自定义框坐标基于屏幕,而摄像头帧坐标系可能存在旋转、比例差异,需要做坐标转换:

  • 通过useRef获取UI框的屏幕布局坐标
  • 根据摄像头的deviceOrientation、帧尺寸与屏幕尺寸的比例,将屏幕坐标转换为帧坐标系下的坐标。

示例转换逻辑:

// 假设UI框的屏幕坐标:{ x: screenX, y: screenY, width: screenW, height: screenH }
// 摄像头帧尺寸:frame.width, frame.height
// 屏幕尺寸:Screen.width, Screen.height

// 计算比例(竖屏场景示例)
const scaleX = frame.width / Screen.width;
const scaleY = frame.height / Screen.height;

// 转换后的自定义框(帧坐标系)
const frameCustomBox = {
  x: screenX * scaleX,
  y: screenY * scaleY,
  width: screenW * scaleX,
  height: screenH * scaleY
};

3. 实现移出判断逻辑

写工具函数判断宠物框是否移出自定义框:

完全移出判断

// 判断宠物框是否完全在自定义框之外
const isPetCompletelyOutOfBox = (petBox, customBox) => {
  const isLeftOutOf = petBox.x + petBox.width <= customBox.x;
  const isRightOutOf = petBox.x >= customBox.x + customBox.width;
  const isTopOutOf = petBox.y + petBox.height <= customBox.y;
  const isBottomOutOf = petBox.y >= customBox.y + customBox.height;

  return isLeftOutOf || isRightOutOf || isTopOutOf || isBottomOutOf;
};

部分移出判断(可选)

如果需要判断宠物超过一半区域移出:

// 计算两个框的重叠区域
const getOverlapArea = (boxA, boxB) => {
  const overlapX = Math.max(0, Math.min(boxA.x + boxA.width, boxB.x + boxB.width) - Math.max(boxA.x, boxB.x));
  const overlapY = Math.max(0, Math.min(boxA.y + boxA.height, boxB.y + boxB.height) - Math.max(boxA.y, boxB.y));
  return overlapX * overlapY;
};

const isPetPartiallyOutOfBox = (petBox, customBox) => {
  const petTotalArea = petBox.width * petBox.height;
  const overlapArea = getOverlapArea(petBox, customBox);
  // 重叠区域小于宠物面积50%则判定为移出
  return overlapArea / petTotalArea < 0.5;
};

4. 告警触发与防抖

避免频繁触发告警,添加冷却时间:

let lastAlertTimestamp = 0;
const ALERT_COOLDOWN = 2000; // 2秒冷却

const triggerAlert = () => {
  const now = Date.now();
  if (now - lastAlertTimestamp < ALERT_COOLDOWN) return;
  
  lastAlertTimestamp = now;
  // 执行告警操作:弹窗、震动、播放提示音等
  Alert.alert('告警', '宠物已移出指定区域!');
};

5. 整合到帧处理器

注意:帧处理器基于worklet运行,不能直接调用JS线程API,需通过事件传递到主线程处理告警:

const frameProcessor = useFrameProcessor((frame) => {
  'worklet';
  const detections = runPetDetection(frame);
  if (detections.length === 0) return;

  const petBox = detections[0].boundingBox;
  const frameCustomBox = getConvertedFrameBox(); // 你的坐标转换函数

  const isOutOfBox = isPetCompletelyOutOfBox(petBox, frameCustomBox);
  if (isOutOfBox) {
    sendEvent('pet-out-of-box', {}); // 发送事件到主线程
  }
}, []);

// 组件中监听事件触发告警
useEffect(() => {
  const subscription = addListener('pet-out-of-box', triggerAlert);
  return () => subscription.remove();
}, []);

注意事项

  • 坐标转换需适配设备旋转,建议在屏幕方向变化时重新计算转换比例。
  • 帧处理器中所有逻辑需符合Reanimated worklet规则,禁止直接调用Alert、AsyncStorage等JS线程API。
  • 宠物检测模型的精度直接影响判断准确性,建议使用针对宠物优化的预训练模型。

内容的提问来源于stack exchange,提问作者Murali Vegesna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 21:50:09