内容目录
原版:基于opencv和mediapipe的手部跟踪小项目
为了手势识别的精确性,考虑将摄像头获得的图像进一步分割,具体表现为,将手部分割出来,并进一步将其处理为128 * 128的图像
完整代码见:github仓库
获取手部矩形图片
# 遍历每个检测到的手
for handLms in results.multi_hand_landmarks:
# 寻找手的边界框
x_list = [lm.x for lm in handLms.landmark]
y_list = [lm.y for lm in handLms.landmark]
xmin, xmax = min(x_list), max(x_list)
ymin, ymax = min(y_list), max(y_list)
# 获取矩形的左上角坐标和边长宽度
top_left_x, top_left_y = int(xmin * img.shape[1]), int(ymin * img.shape[0])
length = int((xmax - xmin) * img.shape[1])
width = int((ymax - ymin) * img.shape[0])
# 裁剪矩形区域
hand_img = img[max(top_left_y-15,0) : min(top_left_y + width + 30,img.shape[0]),
max(top_left_x-15,0) : min(top_left_x + length + 30,img.shape[1])]
将手部21个点的坐标获取之后,分别取其最大最小x、y,以此获取矩形左上角(opencv绘制矩形是通过矩形左上角坐标和长宽来获取)坐标和长宽
裁剪矩形区域时-15、+30是为了保证获取手部的完整(把这些参数去了之后再看看,能够很明显发现有时候裁剪地不完整,毕竟这些坐标是点的坐标)
对图片进行处理
if hand_img is not None:
# 等比例缩放
max_dim = 128
if length > width:
new_length = max_dim
new_width = int(max_dim * (width / length))
else:
new_width = max_dim
new_length = int(max_dim * (length / width))
try:
hand_img_resized = cv2.resize(hand_img, (max(1, new_length), max(1, new_width)),
interpolation=cv2.INTER_AREA)
except Exception as e:
print(f"Error during resizing: {e}")
continue
# 创建一个128x128的黑色背景
background = np.zeros((max_dim, max_dim, 3), dtype=np.uint8)
# 计算将调整后的图像放置在背景中的位置
y_offset = (max_dim - new_width) // 2
x_offset = (max_dim - new_length) // 2
# 将调整后的图像放置在背景中
background[y_offset:y_offset + new_width, x_offset:x_offset + new_length] = hand_img_resized
# 存储到imgs中
imgs.append(background)
最后呈现出来的效果是,将矩形等比例缩放存储在128 * 128的空间内,剩余部分用黑色填充,并且将获得的图片存储到imgs
变量中