kinect的深度图像处理(kinect depth image processing)

2019-10-18 03:40发布

这是我的问题

超高动力学被安装在房间(在天花板上)的顶部。 然后我去Kinect的低于人的深度图像。

所以我得到的是下面的人的顶视图。

然后我想提取人的头数的人数。

因为我看到它的方式,这个问题需要图像的局部最小区域的鉴定。 但我coudn't想出一个办法。

有人建议我的方式来实现这一目标?

是否有一个OpenCV的函数来获取本地最小值区?

谢谢。

Answer 1:

你可以尝试分水岭变换找到局部极小。 快速搜索提出了这个示例代码 ,你可以试试用OpenCV的。



Answer 2:

我会做一个前景背景分割,用于分隔动态的“前景”(人)的静态背景。

然后,一旦你的人的点云/深度地图,您可以细分它们例如与一些区域增长( 颜色填充 )方法。 这样,你得到的分离的人,你可以指望或找到自己的最低点,如果你正在寻找的头特别。



Answer 3:

我会为阈值一样简单的东西近及远的深处走,使用操作合并两个,并找到导致图像中的轮廓。

这不是超级灵活,因为你是那种硬编码的深度范围内(最低人类高度期望的),但它很容易设置/调整和shouldn'be是昂贵的计算。 您也可以选择使用一些模糊和侵蚀/扩张,以帮助改进轮廓。

虽然它有比我更详细地解释,你可以看到一个演示在这里

下面是使用的OpenCV与OpenNI一个基本的例子:

#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#include <iostream>

using namespace cv;
using namespace std;

int threshNear = 60;
int threshFar = 100;
int dilateAmt = 1;
int erodeAmt = 1;
int blurAmt = 1;
int blurPre = 1;
void on_trackbar(int, void*){}

int main( )
{
    VideoCapture capture;
    capture.open(CV_CAP_OPENNI);
    if( !capture.isOpened() )
    {
        cout << "Can not open a capture object." << endl;
        return -1;
    }
    cout << "ready" << endl;
    vector<vector<Point> > contours;
    namedWindow("depth map");
    createTrackbar( "amount dilate", "depth map", &dilateAmt,16, on_trackbar );
    createTrackbar( "amount erode", "depth map", &erodeAmt,16, on_trackbar );
    createTrackbar( "amount blur", "depth map", &blurAmt,16, on_trackbar );
    createTrackbar( "blur pre", "depth map", &blurPre,1, on_trackbar );
    createTrackbar( "threshold near", "depth map", &threshNear,255, on_trackbar );
    createTrackbar( "threshold far", "depth map", &threshFar,255, on_trackbar );
    for(;;)
    {
        Mat depthMap;
        if( !capture.grab() )
        {
            cout << "Can not grab images." << endl;
            return -1;
        }
        else
        {
            if( capture.retrieve( depthMap, CV_CAP_OPENNI_DEPTH_MAP ) )
            {
                const float scaleFactor = 0.05f;
                Mat show; depthMap.convertTo( show, CV_8UC1, scaleFactor );
                //threshold
                Mat tnear,tfar;
                show.copyTo(tnear);
                show.copyTo(tfar);
                threshold(tnear,tnear,threshNear,255,CV_THRESH_TOZERO);
                threshold(tfar,tfar,threshFar,255,CV_THRESH_TOZERO_INV);
                show = tnear & tfar;//or cvAnd(tnear,tfar,show,NULL); to join the two thresholded images
                //filter
                if(blurPre == 1) blur(show,show,Size(blurAmt+1,blurAmt+1));
                Mat cntr; show.copyTo(cntr);
                erode(cntr,cntr,Mat(),Point(-1,-1),erodeAmt);
                if(blurPre == 0) blur(cntr,cntr,Size(blurAmt+1,blurAmt+1));
                dilate(cntr,cntr,Mat(),Point(-1,-1),dilateAmt);

                //compute and draw contours
                findContours(cntr,contours,0,1);
                drawContours(cntr,contours,-1,Scalar(192,0,0),2,3);

                //optionally compute bounding box and circle to exclude small blobs(non human) or do further filtering,etc.
                int numContours = contours.size();
                vector<vector<Point> > contours_poly( numContours );
                vector<Rect> boundRect( numContours );
                vector<Point2f> centers( numContours );
                vector<float> radii(numContours);
                for(int i = 0; i < numContours; i++ ){
                    approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
                    boundRect[i] = boundingRect( Mat(contours_poly[i]) );
                    minEnclosingCircle(contours_poly[i],centers[i],radii[i]);
                    rectangle( cntr, boundRect[i].tl(), boundRect[i].br(), Scalar(64), 2, 8, 0 );
                    circle(cntr,centers[i],radii[i],Scalar(192));
                 }

                imshow( "depth map", show );
                imshow( "contours", cntr );
            }

        }

        if( waitKey( 30 ) == 27 ) break;//exit on esc
    }
}

即使你不使用OpenNI抢你仍然可以插深度图像处理成的OpenCV深度流。 另外,还能检测出边框和圆形这可能有助于过滤事情进一步一点。 说你是建立在一个办公空间,你可能要避免柱,高大的厂房,货架等,所以你可以检查外接圆半径或边框的宽度/高度比率。



文章来源: kinect depth image processing