kinect深度图像处理 [英] kinect depth image processing

查看:333
本文介绍了kinect深度图像处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的问题

Kinect安装在房间顶部(在天花板上)。

Kinect is mounted on top of the room(on ceiling). Then i take a depth image of the people below the kinect.

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

So what i get is a top view of the people below.

然后我想提取人民的头数来计算人数。

Then i want to extract the heads of the people to count the number of people.

按照我看到的方式,这个问题需要识别图像的LOCAL最小区域。

As the way i see it, this problem requires identification of LOCAL minimum regions of the image. But i coudn't figure out a way.

可以有人建议我一种方法来实现这个?

Can some one suggest me a way to achieve this??

是否有OpenCV函数来获取局部最小区域

Is there a OpenCV function to get local minimum regions??

谢谢。

推荐答案

我会使用和近和远深度的阈值一样简单的东西,使用操作合并两个并在结果图像中找到轮廓。

I would go with something as simple as thresholding for near and far depths, using the and operation to merge the two and find the contours in the resulting image.

它不是超级灵活,因为你是一种深度范围的硬编码(预期的最小人类高度),但它很容易设置/调整,应该昂贵的计算。您也可以选择使用模糊处理和磨蚀/膨胀,以帮助细化轮廓。

It's not super flexible as you're kind of hard coding a depth range (a minimum human height expected), but it's easy to setup/tweak and shouldn'be that costly computationally. Optionally you can use a bit of blur and erode/dilate to help refine the contours.

虽然它超出了我的解释,你可以看到一个演示此处

Although it has more than what I explained, you can see a demo here

下面是使用OpenCV和OpenNI的基本示例:

And here's a basic example using OpenCV with 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 。此外,你可以检测边界框和圆,这可能有助于过滤一些东西。假设您设置的是办公空间,您可能需要避免栏,高大的植物,货架等,以便您可以检查边界圆的半径或边框的宽度/高度比。

Even if you're not using OpenNI to grab the depth stream you can still plug the depth image into OpenCV. Also, you can detect the bounding box and circle which might help filter things further a bit. Say you're setup is in an office space, you might want to avoid a column, tall plant,shelves, etc. so you can check the bounding circle's radius or bounding box's width/height ratio.

这篇关于kinect深度图像处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆