【学习日记】win64配置openni的vs2022编译环境

1

在structure官网下载OpenNI的SDK,注意版本对应无误

2

解压后,运行msi文件,安装提示完成安装
在这里插入图片描述

3

安装后,环境变量中自动生成了三项内容

在这里插入图片描述

4

vs2022中的配置:

我选择了release,x64平台。
需要设置三处地方,如下图所示。

1、VC++——包含目录填写上文提到的环境变量OPENNI_INCLUDE64的路径
目录-

2、VC++——库目录填写上文提到的环境变量OPENNI_LIB64的路径

在这里插入图片描述

**3、输出——附加依赖项:**填写OpenNI2.lib
在这里插入图片描述

5 其他注意点

1、网上有人说要把Redist文件和编译生成的exe放在一个文件夹下,不知道为什么。似乎不进行这步操作也没有影响。保险起见,我也在复制了一份放在里面。

在这里插入图片描述

2、程序运行出现如下报错:

Found no files matching 'C:\WINDOWS\SYSTEM32\OpenNI2\Drivers\*.dll'

我直接在System32下自己新建了文件夹,把dll全部复制过去,然后就不会出现这条错误了。

在这里插入图片描述

6 测试是否配置成功

test.cpp

#include <opencv2/opencv.hpp>
#include <OpenNI.h>
#include "opencv2/imgproc/types_c.h"
using namespace openni;
using namespace cv;

class Grabber
{
public:
    void InitOpenNI();
    void InitDevice();
    void InitDepthStream();
    void InitColorStream();
    void Run();

private:
    void CapturePsenseDepthFrame();
    void CapturePsenseColorFrame();
    cv::Mat ChangeDepthForDisplay(const cv::Mat& mat);

    openni::Device* device_;
    openni::VideoStream* depth_stream_;
    openni::VideoStream* color_stream_;
    openni::VideoFrameRef* depth_frame_;
    openni::VideoFrameRef* color_frame_;
};

void Grabber::InitOpenNI()
{
    auto rc = openni::OpenNI::initialize();
    if (rc != openni::STATUS_OK)
    {
        printf("Initialize failed\n%s\n", openni::OpenNI::getExtendedError());
        exit(0);
    }
}

void Grabber::InitDevice()
{
    device_ = new openni::Device();
    auto rc = device_->open(openni::ANY_DEVICE);
    if (rc != openni::STATUS_OK)
    {
        printf("Couldn't open device\n%s\n", openni::OpenNI::getExtendedError());
        exit(0);
    }
}

void Grabber::InitDepthStream()
{
    depth_stream_ = new openni::VideoStream();

    // Create depth stream from device
    if (device_->getSensorInfo(openni::SENSOR_DEPTH) != nullptr)
    {
        auto rc = depth_stream_->create(*device_, openni::SENSOR_DEPTH);
        if (rc != openni::STATUS_OK)
        {
            printf("Couldn't create depth stream\n%s\n", openni::OpenNI::getExtendedError());
            exit(0);
        }
    }

    // Get info about depth sensor
    const openni::SensorInfo& sensor_info = *device_->getSensorInfo(openni::SENSOR_DEPTH);
    const openni::Array<openni::VideoMode>& arr = sensor_info.getSupportedVideoModes();

    // Look for VGA mode in depth sensor and set it for depth stream
    for (int i = 0; i < arr.getSize(); ++i)
    {
        const openni::VideoMode& vmode = arr[i];
        if (vmode.getPixelFormat() == openni::PIXEL_FORMAT_DEPTH_1_MM &&
            vmode.getResolutionX() == 640 &&
            vmode.getResolutionY() == 480)
        {
            depth_stream_->setVideoMode(vmode);
            break;
        }
    }

    // Start the depth stream
    auto rc = depth_stream_->start();
    if (rc != openni::STATUS_OK)
    {
        printf("Couldn't start the depth stream\n%s\n", openni::OpenNI::getExtendedError());
        exit(0);
    }

    depth_frame_ = new openni::VideoFrameRef();
}

void Grabber::InitColorStream()
{
    color_stream_ = new openni::VideoStream();

    if (device_->getSensorInfo(openni::SENSOR_COLOR) != nullptr)
    {
        auto rc = color_stream_->create(*device_, openni::SENSOR_COLOR);
        if (rc != openni::STATUS_OK)
        {
            printf("Couldn't create color stream\n%s\n", openni::OpenNI::getExtendedError());
            exit(0);
        }
    }

    // Get info about color sensor
    const openni::SensorInfo& sensor_info = *device_->getSensorInfo(openni::SENSOR_COLOR);
    const openni::Array<openni::VideoMode>& arr = sensor_info.getSupportedVideoModes();

    // Look for VGA mode and set it for color stream
    for (int i = 0; i < arr.getSize(); ++i)
    {
        const openni::VideoMode& vmode = arr[i];
        if (
            vmode.getResolutionX() == 640 &&
            vmode.getResolutionY() == 480)
        {
            color_stream_->setVideoMode(vmode);
            break;
        }
    }

    // Note: Doing image registration earlier than this seems to fail
    if (device_->isImageRegistrationModeSupported(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR))
    {
        auto rc = device_->setImageRegistrationMode(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR);
        if (rc == openni::STATUS_OK)
            std::cout << "Depth to color image registration set success\n";
        else
            std::cout << "Depth to color image registration set failed\n";
    }
    else
    {
        std::cout << "Depth to color image registration is not supported!!!\n";
    }

    // Start color stream
    auto rc = color_stream_->start();
    if (rc != openni::STATUS_OK)
    {
        printf("Couldn't start the depth stream\n%s\n", openni::OpenNI::getExtendedError());
        exit(0);
    }

    color_frame_ = new openni::VideoFrameRef();
}

void Grabber::CapturePsenseDepthFrame()
{
    auto rc = depth_stream_->readFrame(depth_frame_);
    if (rc != openni::STATUS_OK)
    {
        printf("Read failed!\n%s\n", openni::OpenNI::getExtendedError());
    }

    if (depth_frame_->getVideoMode().getPixelFormat() != openni::PIXEL_FORMAT_DEPTH_1_MM && depth_frame_->getVideoMode().getPixelFormat() != openni::PIXEL_FORMAT_DEPTH_100_UM)
    {
        printf("Unexpected frame format\n");
    }

    // Get pointer to Primesense depth frame
    openni::DepthPixel* dev_buf_ptr = (openni::DepthPixel*)depth_frame_->getData();

    // Copy frame data to OpenCV mat
    cv::Mat depth_mat(depth_frame_->getHeight(), depth_frame_->getWidth(), CV_16U, dev_buf_ptr);

    cv::Mat disp_mat = ChangeDepthForDisplay(depth_mat);

    cv::imshow("Depth", disp_mat);
}

void Grabber::CapturePsenseColorFrame()
{
    // Read from stream to frame
    auto rc = color_stream_->readFrame(color_frame_);
    if (rc != openni::STATUS_OK)
    {
        printf("Read failed!\n%s\n", openni::OpenNI::getExtendedError());
    }

    // Pointer to Primesense color frame
    openni::RGB888Pixel* dev_buf_ptr = (openni::RGB888Pixel*)color_frame_->getData();

    // Make mat from camera data
    cv::Mat color_mat(color_frame_->getHeight(), color_frame_->getWidth(), CV_8UC3, dev_buf_ptr);
    // Convert to BGR format for OpenCV
    cv::cvtColor(color_mat, color_mat, CV_RGB2BGR);

    cv::imshow("Color", color_mat);
}

void Grabber::Run()
{
    openni::VideoStream* streams[] = { depth_stream_, color_stream_ };

    while (true)
    {
        int readyStream = -1;
        auto rc = openni::OpenNI::waitForAnyStream(streams, 2, &readyStream, 2000);
        if (rc != openni::STATUS_OK)
        {
            printf("Wait failed! (timeout is %d ms)\n%s\n", 2000, openni::OpenNI::getExtendedError());
            break;
        }

        switch (readyStream)
        {
        case 0:
            CapturePsenseDepthFrame();
            break;
        case 1:
            CapturePsenseColorFrame();
            break;
        default:
            printf("Unxpected stream\n");
        }

        char c = cv::waitKey(10);
        if ('q' == c)
            break;
    }
}

cv::Mat Grabber::ChangeDepthForDisplay(const cv::Mat& mat)
{
    assert(CV_16U == mat.type());

    const float depth_near = 500;
    const float depth_far = 5000;

    const float alpha = 255.0 / (depth_far - depth_near);
    const float beta = -depth_near * alpha;

    cv::Mat fmat;
    mat.convertTo(fmat, CV_32F);

    for (int r = 0; r < mat.rows; ++r)
    {
        for (int c = 0; c < mat.cols; ++c)
        {
            float v = fmat.at<float>(r, c) * alpha + beta;

            if (v > 255) v = 255;
            if (v < 0)   v = 0;

            fmat.at<float>(r, c) = v;
        }
    }

    cv::Mat bmat;
    fmat.convertTo(bmat, CV_8U);

    cv::Mat cmat;
    cv::cvtColor(bmat, cmat, CV_GRAY2BGR);
    cv::applyColorMap(cmat, cmat, cv::COLORMAP_OCEAN);

    return cmat;
}

int main()
{
    Grabber grabber;
    grabber.InitOpenNI();
    grabber.InitDevice();
    grabber.InitDepthStream();
    grabber.InitColorStream();
    grabber.Run();

    return 0;
}

运行,没有问题,可以顺利看到摄像头画面。显示depth和color图。

在这里插入图片描述

在这里插入图片描述

参考资料

https://structure.io/openni
https://documentation.help/OpenNI-2.0/getting_started.html

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值