React Native带鼻部定位网格、距离预警、光照检测的相机方案咨询
方案推荐与示例代码
目前没有同时覆盖你所有需求的现成npm包,但可以通过组合几个主流React Native库来实现全部功能,核心依赖选择react-native-vision-camera(支持实时帧处理)、@react-native-ml-kit/face-detection(面部/鼻部识别)和react-native-sensors(光照检测)。
1. 安装依赖
# 核心相机与面部检测库 npm install react-native-vision-camera @react-native-ml-kit/face-detection # 光照传感器库 npm install react-native-sensors
权限配置:
- iOS:在
Info.plist中添加相机权限描述<key>NSCameraUsageDescription</key> <string>需要使用相机进行面部识别</string> - Android:在
AndroidManifest.xml中添加相机和传感器权限<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" />
2. 完整示例代码
import React, { useState, useEffect } from 'react'; import { View, StyleSheet, Text } from 'react-native'; import { Camera, useCameraDevices, useFrameProcessor, runOnJS } from 'react-native-vision-camera'; import { scanFaces } from '@react-native-ml-kit/face-detection'; import { LightSensor } from 'react-native-sensors'; const CameraScreen = () => { const [hasPermission, setHasPermission] = useState(false); const devices = useCameraDevices(); const device = devices.back; // 鼻部定位坐标 const [nosePosition, setNosePosition] = useState({ x: 0, y: 0 }); // 距离预警状态 const [distanceAlert, setDistanceAlert] = useState(false); // 光照提示 const [lightAlert, setLightAlert] = useState(''); // 请求相机权限 useEffect(() => { (async () => { const status = await Camera.requestCameraPermission(); setHasPermission(status === 'authorized'); })(); }, []); // 光照强度检测 useEffect(() => { const subscription = LightSensor.subscribe(({ value }) => { if (value < 50) { setLightAlert('光照过弱,请调整环境'); } else if (value > 10000) { setLightAlert('光照过强,请调整环境'); } else { setLightAlert(''); } }); return () => subscription.unsubscribe(); }, []); // 实时帧处理:鼻部识别+距离计算 const frameProcessor = useFrameProcessor((frame) => { 'worklet'; const faces = scanFaces(frame, { enableContours: true, enableTracking: true, }); if (faces.length === 0) { runOnJS(setNosePosition)({ x: 0, y: 0 }); runOnJS(setDistanceAlert)(false); return; } const face = faces[0]; // 计算鼻部中心点坐标 const noseContour = face.contours?.noseBase; if (noseContour) { const avgX = noseContour.points.reduce((sum, p) => sum + p.x, 0) / noseContour.points.length; const avgY = noseContour.points.reduce((sum, p) => sum + p.y, 0) / noseContour.points.length; // 转换为屏幕坐标 runOnJS(setNosePosition)({ x: (avgX / frame.width) * StyleSheet.flatten(styles.camera).width, y: (avgY / frame.height) * StyleSheet.flatten(styles.camera).height, }); } // 估算距离:基于面部宽度(取成年人鼻宽5cm为参考) const faceWidth = face.bounds.size.width; const focalLength = 1000; // 适配多数设备的经验值,可根据实际相机参数调整 const realNoseWidth = 5; // 实际鼻宽(单位:cm) const distanceCm = (realNoseWidth * focalLength) / faceWidth; const distanceM = distanceCm / 100; runOnJS(setDistanceAlert)(distanceM > 2); }, []); if (!device || !hasPermission) { return <View style={styles.container}><Text>加载中...</Text></View>; } return ( <View style={styles.container}> <Camera style={styles.camera} device={device} isActive={true} frameProcessor={frameProcessor} frameProcessorFps={5} // 降低帧率减少性能消耗 /> {/* 网格+提示层 */} <View style={styles.overlay}> {/* 3x3参考网格 */} {[0,1,2].map(row => ( <View key={`row-${row}`} style={styles.gridRow}> {[0,1,2].map(col => ( <View key={`col-${col}`} style={styles.gridCell} /> ))} </View> ))} {/* 鼻部定位指针 */} {nosePosition.x !== 0 && ( <View style={[ styles.nosePointer, { left: nosePosition.x - 10, top: nosePosition.y - 10 } ]} /> )} {/* 预警提示 */} {(distanceAlert || lightAlert) && ( <Text style={styles.alertText}> {distanceAlert ? '距离过远,请靠近至2米内' : lightAlert} </Text> )} </View> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', }, camera: { width: '100%', height: '100%', }, overlay: { position: 'absolute', width: '100%', height: '100%', justifyContent: 'center', }, gridRow: { flexDirection: 'row', marginVertical: '15%', justifyContent: 'center', }, gridCell: { width: 2, height: '25%', backgroundColor: '#fff', marginHorizontal: '5%', }, nosePointer: { position: 'absolute', width: 20, height: 20, borderRadius: 10, borderWidth: 2, borderColor: 'red', backgroundColor: 'rgba(255,0,0,0.3)', }, alertText: { position: 'absolute', bottom: 50, alignSelf: 'center', backgroundColor: 'rgba(255,0,0,0.8)', color: '#fff', paddingHorizontal: 15, paddingVertical: 8, borderRadius: 5, fontSize: 16, }, }); export default CameraScreen;
关键说明
- 鼻部识别:通过ML Kit的面部轮廓检测获取鼻部坐标,实时更新定位指针位置。
- 距离估算:基于面部像素宽度和实际参考尺寸(鼻宽),结合相机焦距估算距离,可根据设备实际相机参数调整
focalLength值提升精度。 - 光照检测:利用
react-native-sensors的光线传感器,根据光照强度阈值触发提示。
内容的提问来源于stack exchange,提问作者Deepika
相关产品推荐
相关产品推荐

