React Native Expo相机模型推理报错:输入形状不匹配求助
解决React Native Expo物体识别模型输入形状不匹配问题
问题原因
报错明确显示模型期望输入形状为[null,32,32,1],但你传入的张量形状是[1,32,32,3]。对比Python代码和RN代码,核心差异在图像预处理步骤:
- Python代码中,读取图像后调用了
preprocessing(img)(推测是将RGB图转为单通道灰度图),再通过reshape(1,32,32,1)将通道数固定为1; - RN代码中直接使用摄像头输出的三通道RGB张量,未做灰度转换和通道压缩,导致形状不匹配。
修复步骤
1. 补充灰度转换与归一化
在处理摄像头张量时,添加RGB转灰度图的逻辑,同时补充Python中preprocessing对应的归一化操作(通常是将像素值除以255)。
2. 修正异步权限请求
原代码中loadModel函数调用fn_requestPermisison()时未加await,导致权限判断逻辑失效,需要补全异步等待。
3. 优化摄像头配置
将TensorCamera的resizeDepth设为1,直接输出单通道灰度图,减少后续处理开销(可选,但能提升性能)。
修改后的关键代码
修正后的loadModel函数
const loadModel = useCallback(async () => { const isAllowedCamera = await fn_requestPermisison(); // 补全await if (!isAllowedCamera) return; console.log("[+] Application started"); await tf.ready(); console.log("[+] Loading custom mask detection model"); const modelJson = require("./assets/AIDatas/model.json"); const modelWeight = require("./assets/AIDatas/group1-shard1of1.bin"); const newSignDetector = await tf.loadLayersModel( bundleResourceIO(modelJson, modelWeight) ); console.log("[+] Model Loaded"); setSignDetector(newSignDetector); }, []);
修正后的图像预处理逻辑(fn_onReadyTensorCamera内)
const loop = async () => { if (signDetector !== undefined) { const nextImageTensor = tf.image.resizeBilinear( images.next().value, [32, 32], true ); // RGB转灰度图,形状变为[32,32,1] const grayImageTensor = tf.image.rgbToGrayscale(nextImageTensor); // 归一化(对应Python的preprocessing,根据实际预处理逻辑调整) const normalizedTensor = tf.div(grayImageTensor, 255); // 扩展batch维度,最终形状为[1,32,32,1] const expandedImageTensor = tf.expandDims(normalizedTensor, 0); console.log("expandedImageTensor shape:", expandedImageTensor.shape); await fn_estimateBlazeFace(expandedImageTensor) .then((isEstimate) => { console.log("result", isEstimate); }) .catch((error) => { console.log(error); }); // 统一用requestAnimationFrame控制帧率,避免混用setTimeout requestAnimationFrame(loop); } }; loop();
优化后的TensorCamera配置
<TensorCamera ref={tensorCameraRef} style={styles.camera} type={CameraType.back} cameraTextureHeight={textureDims.height} cameraTextureWidth={textureDims.width} resizeHeight={CAMERA_SIZE.height} resizeWidth={CAMERA_SIZE.width} resizeDepth={1} // 改为1,直接输出单通道灰度图 autorender={true} useCustomShadersToResize={false} onReady={fn_onReadyTensorCamera} />
额外注意事项
- 确认Python中
preprocessing的具体逻辑,如果包含除灰度化和归一化之外的操作(比如均值减法),需要在RN代码中同步实现; - 避免Tensor内存泄漏,处理完张量后可以调用
dispose()释放资源,示例:nextImageTensor.dispose(); grayImageTensor.dispose(); normalizedTensor.dispose(); expandedImageTensor.dispose();
内容的提问来源于stack exchange,提问作者박재우
相关产品推荐
相关产品推荐

