使用PIL ImageDraw.Draw.line()连接Movenet关节点无效果问题求助
解决PIL绘制Movenet骨架连线不显示的问题
核心排查与修正方案
1. 优先检查坐标转换
Movenet输出的是归一化坐标(0-1范围),绘制椭圆时你可能已经转换为像素坐标,但连线时大概率漏了这一步——直接用归一化坐标绘制的线条会集中在图像左上角极小区域,肉眼不可见。
2. 修正代码示例
假设你的原代码如下(结合你提到的pose数组格式):
from PIL import Image, ImageDraw import numpy as np # Movenet输出的pose数组:[x(归一化), y(归一化), 置信度] pose = np.array([ [0.5, 0.1, 0.9], [0.45, 0.2, 0.8], [0.55, 0.2, 0.8], [0.4, 0.3, 0.7], [0.6, 0.3, 0.7], [0.35, 0.5, 0.9], [0.65, 0.5, 0.9], [0.3, 0.7, 0.8], [0.7, 0.7, 0.8], [0.25, 0.9, 0.7], [0.75, 0.9, 0.7] ]) img = Image.open("input.jpg").convert("RGB") width, height = img.size draw = ImageDraw.Draw(img) # 成功绘制关节椭圆的代码 for point in pose: x, y, score = point if score > 0.5: x_pix = int(x * width) y_pix = int(y * height) draw.ellipse([x_pix-5, y_pix-5, x_pix+5, y_pix+5], fill="red", outline="white") # 修正前连线不显示的代码(问题出在未转像素坐标) # skeleton_pairs = [(0,5), (0,6), (5,7), (7,9), (6,8), (8,10)] # for pair in skeleton_pairs: # idx1, idx2 = pair # p1, p2 = pose[idx1], pose[idx2] # draw.line([p1[0], p1[1], p2[0], p2[1]], fill="blue", width=3) # 修正后的连线代码 skeleton_pairs = [(0,5), (0,6), (5,7), (7,9), (6,8), (8,10)] for pair in skeleton_pairs: idx1, idx2 = pair p1, p2 = pose[idx1], pose[idx2] # 过滤低置信度关节点,避免无效连线 if p1[2] > 0.5 and p2[2] > 0.5: # 转换为像素坐标 x1, y1 = int(p1[0] * width), int(p1[1] * height) x2, y2 = int(p2[0] * width), int(p2[1] * height) # 使用高对比度颜色+足够宽度 draw.line([(x1, y1), (x2, y2)], fill="limegreen", width=3) img.save("output.jpg")
3. 其他可能的问题点
- 线条颜色/宽度:如果线条颜色与背景色一致(比如背景白色用白色线条),或宽度设为0,会导致不可见,建议用高对比度颜色(如limegreen、深蓝色)并设置宽度≥2。
- Draw对象复用:确保连线使用的是同一个
ImageDraw.Draw实例,不要在绘制椭圆后重新创建Draw或加载图像,否则之前的绘制会被覆盖。 - 绘制顺序:如果线条被椭圆覆盖,可调整绘制顺序(先画线条再画椭圆)。
内容的提问来源于stack exchange,提问作者M.K
相关产品推荐
相关产品推荐

