使用Mediapipe手部检测时,切片numpy数组创建mp.Image触发TypeError
Mediapipe手部检测切片操作引发TypeError的问题解析
问题场景
使用Mediapipe做手部检测时,运行以下代码触发TypeError:
cv_mat = cv2.imread("hand.jpg") cv_mat = cv_mat[..., ::-1] image = mp.Image(image_format=mp.ImageFormat.SRGB, data=cv_mat)
错误日志如下:
INFO: Created TensorFlow Lite XNNPACK delegate for CPU. Traceback (most recent call last): image = mp.Image(image_format=mp.ImageFormat.SRGB, data=cv_mat) TypeError: __init__(): incompatible constructor arguments. The following argument types are supported: 1. mediapipe.python._framework_bindings.image.Image(image_format: mediapipe::ImageFormat_Format, data: numpy.ndarray[numpy.uint8]) 2. mediapipe.python._framework_bindings.image.Image(image_format: mediapipe::ImageFormat_Format, data: numpy.ndarray[numpy.uint16]) 3. mediapipe.python._framework_bindings.image.Image(image_format: mediapipe::ImageFormat_Format, data: numpy.ndarray[numpy.float32]) Invoked with: kwargs: image_format=<ImageFormat.SRGB: 1>, data=array([[[255, 255, 255],...
移除cv_mat = cv_mat[..., ::-1]后程序正常运行,疑问点:
- 报错根源是什么?
- 切片操作会不会改变数组类型?
- 为什么切片后的数组在OpenCV中能用,Mediapipe却报错?
问题分析与解决
- 切片不改变数组类型:
[...,::-1]只是反转数组的通道顺序(把OpenCV默认的BGR格式转为RGB),数组的数据类型还是uint8,和原始数组完全一致,用print(cv_mat.dtype)就能验证。 - 真正报错原因:内存布局非连续:numpy的切片操作生成的是原数组的「视图」,而非独立的新数组,这个视图的内存地址是分散的(非连续)。Mediapipe的
mp.Image构造函数要求输入的numpy数组必须是内存连续的,但OpenCV的大多数函数兼容非连续数组,这就是两者表现不同的核心原因。 - 解决办法:将切片后的数组转为内存连续的数组即可,有两种方式:
- 用
numpy.ascontiguousarray()处理切片后的数组:
import numpy as np import cv2 import mediapipe as mp cv_mat = cv2.imread("hand.jpg") cv_mat = cv_mat[..., ::-1] cv_mat = np.ascontiguousarray(cv_mat) # 转为连续内存数组 image = mp.Image(image_format=mp.ImageFormat.SRGB, data=cv_mat)- 直接用OpenCV的
cv2.cvtColor完成通道转换,该函数返回的数组天然是内存连续的:
import cv2 import mediapipe as mp cv_mat = cv2.imread("hand.jpg") cv_mat = cv2.cvtColor(cv_mat, cv2.COLOR_BGR2RGB) image = mp.Image(image_format=mp.ImageFormat.SRGB, data=cv_mat) - 用
内容的提问来源于stack exchange,提问作者Vladimir Ilyin
相关产品推荐
相关产品推荐

