KinectV2绘制人体外接矩形时最右点检测异常问题求解
问题根因
- 边界计算逻辑完全错误:要绘制人体外接矩形,需要同时获取所有有效人体像素的最小x(最左)、最大x(最右)、最小y(最高点,Processing坐标系y轴向下,值越小位置越靠上)、最大y(最低点,值越大位置越靠下)四个边界值。原代码仅单独追踪最左、最右像素的x值,直接把最左/最右列遍历到的最后一个像素的y值当作顶点y坐标,根本无法得到正确的矩形角点,你认为的“最左点、最高点正常”只是巧合现象。
- 最右点x轴固定的直接原因:画面最右侧边缘存在持续符合深度阈值的固定噪点/背景像素,每次遍历都会将
rightRecord更新为该噪点所在的最大x值,因此rx不会随人体移动变化;而噪点在列内的y位置随机波动,就会出现标记点仅沿y轴上下跳动的现象。 - 存在无效判断:代码中
x < kinect2.depthWidth属于冗余逻辑,x的循环边界已经保证该条件恒成立,没有实际作用。
修正方案
- 每帧遍历深度数据前,重置四个边界变量的初始值:最小x初始为深度图宽度(大于所有可能的x值),最大x初始为-1(小于所有可能的x值),最小y初始为深度图高度,最大y初始为-1。
- 遍历到符合阈值的人体像素时,同步更新四个边界值,无需绑定单个点的x、y坐标。
- 遍历完成后增加有效性判断,仅当检测到有效人体像素时再绘制标记和外接矩形,避免空数据报错。
- (可选)如果需要过滤边缘孤立噪点,可以增加有效像素计数逻辑,仅当连续区域像素数达到阈值时才判定为人体区域。
修正后完整代码
import org.openkinect.processing.*; Kinect2 kinect2; float minThresh = 420; float maxThresh = 1500; PImage img; void setup() { size(512, 424); kinect2 = new Kinect2(this); kinect2.initDepth(); kinect2.initDevice(); img = createImage(kinect2.depthWidth, kinect2.depthHeight, RGB); } void draw() { background(0); img.loadPixels(); PImage dImg = kinect2.getDepthImage(); int[] depth = kinect2.getRawDepth(); // 初始化四个边界值 int minX = kinect2.depthWidth; int maxX = -1; int minY = kinect2.depthHeight; int maxY = -1; for (int x = 0; x < kinect2.depthWidth; x++) { for (int y = 0; y < kinect2.depthHeight; y++) { int offset = x + y*kinect2.depthWidth; int d = depth[offset]; // 深度阈值判断,x>50为左侧区域过滤,可根据实际需求调整 if (d > minThresh && d < maxThresh && x>50) { img.pixels[offset] = color(255, 0, 150); // 更新四个边界 if (x < minX) minX = x; if (x > maxX) maxX = x; if (y < minY) minY = y; if (y > maxY) maxY = y; } else { img.pixels[offset] = dImg.pixels[offset]; } } } img.updatePixels(); image(img, 0, 0); // 仅当检测到有效人体区域时绘制 if (maxX != -1) { fill(150, 0, 255); // 左上角标记 ellipse(minX, minY, 30, 30); // 右下角标记 ellipse(maxX, maxY, 30, 30); // 绘制外接矩形边框 noFill(); stroke(255, 0, 0); strokeWeight(2); rect(minX, minY, maxX - minX, maxY - minY); } }
内容的提问来源于stack exchange,提问作者gigi
相关产品推荐
相关产品推荐

