使用OpenCV和OpenNI测量2个点之间的距离 [英] Measuring distance between 2 points with OpenCV and OpenNI

查看:1360
本文介绍了使用OpenCV和OpenNI测量2个点之间的距离的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在OpenCV 2.4.0中使用内置的OpenNI访问,我试图测量深度图中两点之间的距离。我试过这么远:

I'm playing with the built in OpenNI access within OpenCV 2.4.0 and I'm trying to measure the distance between two points in the depth map. I've tried this so far:

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

#include <iostream>

using namespace cv;
using namespace std;

Point startPt(0,0);
Point endPt(0,0);

void onMouse( int event, int x, int y, int flags, void* )
{
    if( event == CV_EVENT_LBUTTONUP) startPt = Point(x,y);
    if( event == CV_EVENT_RBUTTONUP) endPt   = Point(x,y);
}

int main( int argc, char* argv[] ){
    VideoCapture capture;
    capture.open(CV_CAP_OPENNI);
    //capture.set( CV_CAP_PROP_OPENNI_REGISTRATION , 0);
    unsigned t0=clock();
    if( !capture.isOpened() ){
        cout << "Can not open a capture object." << endl;
        return -1;
    }
    unsigned elapsed=clock()-t0;
    cout << "initialized in "<< elapsed <<" s. ready!" << endl;
    namedWindow( "depth", 1 );
    setMouseCallback( "depth", onMouse, 0 );
    for(;;){
        Mat depthMap;
        if( !capture.grab() ){
            cout << "Can not grab images." << endl;
            return -1;
        }else{
            Mat show,real,valid;
            if( capture.retrieve( depthMap, CV_CAP_OPENNI_DEPTH_MAP ) ){
                depthMap.convertTo( show, CV_8UC1, 0.05f);
            }
            capture.retrieve(valid,CV_CAP_OPENNI_VALID_DEPTH_MASK);
            if( capture.retrieve(real, CV_CAP_OPENNI_POINT_CLOUD_MAP)){
                unsigned int sp = valid.at<unsigned char>(startPt.x, startPt.y);
                unsigned int ep = valid.at<unsigned char>(endPt.x, endPt.y);
                if(sp == 255 && ep == 255){
                    Vec3f s = real.at<Vec3f>(startPt.x, startPt.y);
                    Vec3f e = real.at<Vec3f>(endPt.x, endPt.y);
                    float dx = e[0]-s[0];
                    float dy = e[1]-s[1];
                    float dz = e[2]-s[2];
                    float dist = sqrt(dx*dx + dy*dy + dz*dz);
                    putText(show,format("distance: %f m\n",dist),Point(10,10),FONT_HERSHEY_PLAIN,1,Scalar(255));
                }
            }
            circle(show,startPt,3,Scalar(255),3);
            circle(show,endPt,3,Scalar(192),3);
            line(show,startPt,endPt,Scalar(128));
            imshow("depth",show);
        }
        if( waitKey( 30 ) >= 0 )    break;
    }

}

但我有几个问题:


  1. 除非我检查有效深度掩码中的值,否则程序
    有时会崩溃/ li>
  2. 据我所知,点云地图返回以米为单位的XYZ数据(CV_32FC3),但是我在屏幕上看到的数字看起来是错误的。

我使用正确的方式检索xyz值和计算距离?

Am I using the correct way to retrieve xyz values and compute distances ?

我可能会遗漏任何详细资料?

Any detail I might be missing ?

推荐答案


  1. 我运行的代码,但我不能让它崩溃即使当我注释 if(sp == 255&& ep == 255)。它经常发生吗?我没有使用OpenNI驱动程序,但在微软的驱动程序,例如,也有一个无效的值(例如,当表面是镜面的)。对于太近或太远也有不同的值。可能是OpenNI返回的垃圾在这样的情况下?

  1. I ran the code but I couldn't make it crash even when I commented out if(sp == 255 && ep == 255). Does it happen often? I haven't worked with the OpenNI drivers, but in the Microsoft drivers for example there is also an invalid value (for example when the surface is specular). There are also different values for 'too near' or 'too far'. Could it be that OpenNI returns garbage in a case like that?

尝试切换x和y:

Vec3f s = real.at<Vec3f>(startPt.y, startPt.x);        
Vec3f e = real.at<Vec3f>(endPt.y, endPt.x);        




(and consequently:)

unsigned int sp = valid.at<unsigned char>(startPt.y, startPt.x);
unsigned int ep = valid.at<unsigned char>(endPt.y, endPt.x);

语法为 cv :: Mat :: at< _Tp> y,int x)或者如果它帮助你更好 cv :: Mat :: at< _Tp>(int row,int column)
我测量了一些距离,它对我来说很好。

The syntax is cv::Mat::at<_Tp>(int y, int x) or if it helps you better cv::Mat::at<_Tp>(int row, int column) I measured some distances and it worked fine for me.

此外,你实际计算的3D点和你获得的每一帧的距离,是目的?因为即使您在图像中选择两个2D点一次,您用于计算距离的相应3D点可能会由于噪音而在每个帧中更改。

Also, you actually calculate the 3D points and the distance for every frame that you get, is that on purpose? Because even though you choose two 2D points in the image once, the corresponding 3D points that you use to calculate the distance may change in every frame due to noise.

这篇关于使用OpenCV和OpenNI测量2个点之间的距离的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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