分割手部图像
内容目录

原版:基于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变量中

效果

image.png

上一篇
下一篇