c++ - Kinect RGB相机通过使用opencv裁剪图像而不是完整图像

标签 c++ opencv kinect

我试图从Microsoft Kinect V1中提取RGB和深度图像,我也使用OpenCV 3.4从Kinect中显示图像。这是以下代码,我正在为Ubuntu和OpenCV使用libfreenect驱动程序:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <libfreenect/libfreenect.hpp>
#include <pthread.h>
#define CV_NO_BACKWARD_COMPATIBILITY
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#define FREENECTOPENCV_WINDOW_D "Depthimage"
#define FREENECTOPENCV_WINDOW_N "Normalimage"
#define FREENECTOPENCV_RGB_DEPTH 3
#define FREENECTOPENCV_DEPTH_DEPTH 1
#define FREENECTOPENCV_RGB_WIDTH 640
#define FREENECTOPENCV_RGB_HEIGHT 480
#define FREENECTOPENCV_DEPTH_WIDTH 640
#define FREENECTOPENCV_DEPTH_HEIGHT 480

using namespace cv;
using namespace std;

Mat depthimg, rgbimg, tempimg, canny_temp, canny_img;

pthread_mutex_t mutex_depth = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_rgb = PTHREAD_MUTEX_INITIALIZER;
pthread_t cv_thread;

// callback for depthimage, called by libfreenect
void depth_cb(freenect_device *dev, void *depth, uint32_t timestamp)

{
    Mat depth8;
    Mat mydepth = Mat( FREENECTOPENCV_DEPTH_WIDTH,FREENECTOPENCV_DEPTH_HEIGHT, CV_16UC1, depth);

    mydepth.convertTo(depth8, CV_8UC1, 1.0/4.0);
    pthread_mutex_lock( &mutex_depth );
    memcpy(depthimg.data, depth8.data, 640*480);
    // unlock mutex
    pthread_mutex_unlock( &mutex_depth );

}

// callback for rgbimage, called by libfreenect

void rgb_cb(freenect_device *dev, void *rgb, uint32_t timestamp)
{

    // lock mutex for opencv rgb image
    pthread_mutex_lock( &mutex_rgb );
    memcpy(rgbimg.data, rgb, 640*480);
    // unlock mutex
    pthread_mutex_unlock( &mutex_rgb );
}

/*
 * thread for displaying the opencv content
 */
void *cv_threadfunc (void *ptr) {
    depthimg = Mat(FREENECTOPENCV_DEPTH_HEIGHT, FREENECTOPENCV_DEPTH_WIDTH, CV_8UC1);
    rgbimg = Mat(FREENECTOPENCV_RGB_HEIGHT, FREENECTOPENCV_RGB_WIDTH, CV_8UC3);
    tempimg = Mat(FREENECTOPENCV_RGB_HEIGHT, FREENECTOPENCV_RGB_WIDTH, CV_8UC3);
    canny_img = Mat(FREENECTOPENCV_RGB_HEIGHT, FREENECTOPENCV_RGB_WIDTH, CV_8UC1);
    canny_temp = Mat(FREENECTOPENCV_DEPTH_HEIGHT, FREENECTOPENCV_DEPTH_WIDTH, CV_8UC3);

    // use image polling
    while (1)
    {
        //lock mutex for depth image
        pthread_mutex_lock( &mutex_depth );

        imshow(FREENECTOPENCV_WINDOW_D,depthimg);
        pthread_mutex_unlock( &mutex_depth );

        //lock mutex for rgb image
        pthread_mutex_lock( &mutex_rgb );

        cvtColor(rgbimg,tempimg,CV_BGR2RGB);
        cvtColor(tempimg, canny_img, CV_BGR2GRAY);

        imshow(FREENECTOPENCV_WINDOW_N, rgbimg);

        //unlock mutex
        pthread_mutex_unlock( &mutex_rgb );

        // wait for quit key
        if(cvWaitKey(15) == 27)
            break;

    }
    pthread_exit(NULL);

    return NULL;

}

int main(int argc, char **argv)
{

    freenect_context *f_ctx;
    freenect_device *f_dev;

    int res = 0;
    int die = 0;
    printf("Kinect camera test\n");

    if (freenect_init(&f_ctx, NULL) < 0)
    {
        printf("freenect_init() failed\n");
        return 1;
    }

    if (freenect_open_device(f_ctx, &f_dev, 0) < 0)
    {
        printf("Could not open device\n");
        return 1;
    }

    freenect_set_depth_callback(f_dev, depth_cb);
    freenect_set_video_callback(f_dev, rgb_cb);
    //freenect_set_video_format(f_dev, FREENECT_VIDEO_RGB);

    // create opencv display thread
    res = pthread_create(&cv_thread, NULL, cv_threadfunc, NULL);
    if (res)
    {
        printf("pthread_create failed\n");
        return 1;
    }
    printf("init done\n");

    freenect_start_depth(f_dev);
    freenect_start_video(f_dev);

    while(!die && freenect_process_events(f_ctx) >= 0 );
}

这是Kinect的结果:
result

为什么RGB摄像机的输出会减半?任何援助将不胜感激。

最佳答案

在使用OpenCV处理移动应用程序并尝试显示结果时,我看到了类似的行为。我不能完全弄清问题是什么,但是当您为矩阵(在先前的操作中)迭代分配的内存(在先前的操作中)预分配内存时,似乎显示了图像的“损坏”版本。

例如,您准备一个垫子来存储恒定的视频帧流,并不断地在循环中重复使用它。我不确定这是否是您的确切情况。您可以将镜像写入磁盘,然后查看此结果是否也被“裁剪”吗?

关于c++ - Kinect RGB相机通过使用opencv裁剪图像而不是完整图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59969602/

相关文章:

c++ - 可以使用 C++ 聚合初始化来构造实现接口(interface)的类的实例吗?

c++ - Blowfish 密码在加密和解密过程中弄乱了前 8 个字节

c++ - 如何正确进行图像反投影?

python - 如何分段弯杆进行角度计算?

windows - 使用 OpenNI2 和 NiViewer 初始化 StructureSensor 时出错

c++ - 我需要 C++ 中的 UnSupportedOperationException

video - 用opencv进行视频处理

opencv - 使用 OpenCV 录制视频失败,但没有给出错误

c# - Kinect:计算头部的俯仰角、偏航角、滚动角

c#-4.0 - 如何在Kinect SDK V1.7 (Avateering XNA) 中捕捉运动数据?