返回上级
共12条
跳至  页 
  • 阅读数:429发布于2021-04-16 01:50:54

    只看该作者
    MFC下的OpenNI2环境的配置以及ColorPool彩色图像的输出 复制本文链接
    1.下载并安装OpenNI2
    2.在VS2019项目下,打开项目列表中的属性,调整:配置-Debug, 平台-x64,打开VC++目录下的包含目录,添加
    C:\Program Files\OpenNI2\IncludeVC++目录下的库目录下添加
    C:\Program Files\OpenNI2\Lib
    
    
    在链接器目录下的输入中的附加依赖项中添加
    OpenNI2.libOpenNI2OpenNI.iniOpenNI2.dllSonixCamera.dll复制到项目的bebug文件夹下或者复制到系统的system32

    // ColorPool.h
    
    #pragma once
    #include 
    using namespace openni;
    // Callback object that show images
    class PrintCallback : public VideoStream::NewFrameListener
    {
    public:
        inline void SetWndHandle(HWND hWnd) { m_hWnd = hWnd; }
    
        static void AnalyzeFrame(HWND hWnd, const VideoFrameRef& frame);
    
        void onNewFrame(VideoStream& stream)
        {
            stream.readFrame(&m_frame);
            AnalyzeFrame(m_hWnd, m_frame);
        }
    
        inline HWND GetWndHandle() const { return m_hWnd; }
    
    private:
        VideoFrameRef m_frame;
        HWND m_hWnd = NULL;
    };
    
    class ColorPool
    {
    public:
        BOOL SetWndHandle(HWND hWnd);
    
        BOOL Init();
        void Close();
        BOOL FrameListener();
    
    private:
        void StopFrame() { m_color.stop(); }
        void DestroyFrame() { m_color.destroy(); }
        void CloseDevice() { m_device.close(); }
        void ShutDown() { OpenNI::shutdown(); }
    private:
        void ShowError(const char* pDescribe, const char* pError);
        Status m_retCode;
        Device m_device;
        VideoStream m_color;
        PrintCallback m_colorPrinter;
    };
    

    // ColorPool.cpp
    
    #include "pch.h"
    #include "ColorPool.h"
    
    void PrintCallback::AnalyzeFrame(HWND hWnd, const VideoFrameRef& frame)
    {
        RGB888Pixel* pColor;
        HDC hdc = GetDC(hWnd);
        int h = frame.getHeight();
        int w = frame.getWidth();
    
        switch (frame.getVideoMode().getPixelFormat())
        {
        case PIXEL_FORMAT_RGB888:
            pColor = (RGB888Pixel*)frame.getData();  // get array' address of image that in pixels
            // traverses the pixels according to the height and width of the image
            for (int i = 0; i < h; i++)              
            {
                for (int j = 0; j < w; j++)
                {
                    COLORREF& d = (COLORREF&)pColor[i * w + j];  // mandatory reference  3bytes? 4bytes? 
                    SetPixel(hdc, j, i, d & 0x00ffffff);         // putout pixel
                }
            }
            ReleaseDC(hWnd, hdc);
            break;
        default:
            ::MessageBox(hWnd, L"Unknown format\n", _T("错误提示"), MB_OK);
            break;
        }
    }
    
    /***************************************************/
    BOOL ColorPool::SetWndHandle(HWND hWnd)
    {
        if (hWnd == NULL) 
            return FALSE;
        m_colorPrinter.SetWndHandle(hWnd);
        return TRUE;
    }
    
    BOOL ColorPool::Init()
    {
        m_retCode = OpenNI::initialize();
        if (m_retCode != STATUS_OK)
        {
            ShowError("Initialize failed\n%s\n", OpenNI::getExtendedError());
            return FALSE;
        }
    
        m_retCode = m_device.open(ANY_DEVICE);
        if (m_retCode != STATUS_OK)
        {
            ShowError("Couldn't open device\n%s\n", OpenNI::getExtendedError());
            return FALSE;
        }
    
        if (NULL != m_device.getSensorInfo(SENSOR_COLOR))
        {
            m_retCode = m_color.create(m_device, SENSOR_COLOR);
            if (m_retCode != STATUS_OK)
            {
                ShowError("Couldn't create depth stream\n%s\n", OpenNI::getExtendedError());
                return FALSE;
            }
        }
    
        m_retCode = m_color.start();
        if (m_retCode != STATUS_OK)
        {
            ShowError("Couldn't start the depth stream\n", OpenNI::getExtendedError());
            return FALSE;
        }
    
        return TRUE;
    }
    
    void ColorPool::Close()
    {
        // if status ok, should remove frames from Frame listener
        if (m_retCode == STATUS_OK)  
        {
            Sleep(100);
            m_color.removeNewFrameListener(&m_colorPrinter);
        }
        // related operations when closing
        StopFrame();
        DestroyFrame();
        CloseDevice();
        ShutDown();
    }
    
    BOOL ColorPool::FrameListener()
    {
        m_retCode = m_color.addNewFrameListener(&m_colorPrinter);
        if (m_retCode != STATUS_OK)  // if status is not ok then close camera
        {
            Sleep(100);
            m_color.removeNewFrameListener(&m_colorPrinter);
            Close();
            return FALSE;
        }
    
        return TRUE;
    }
    
    void ColorPool::ShowError(const char* pDescribe, const char* pError)
    {
        if (!pDescribe || !pError)
            return;
    
        CString str1, str2;
        str1 = pDescribe, str2 = pError;
        str1 += str2;
    
        ::MessageBox(m_colorPrinter.GetWndHandle(), str1, _T("错误提示"), MB_OK);
    }
    

    // TestColorPoolDlg.h : header file
    //
    
    #pragma once
    #include "ColorPool.h"
    
    // CTestColorPoolDlg dialog
    class CTestColorPoolDlg : public CDialogEx
    {
        ColorPool m_colorPool;
        BOOL GetImgStreams();
    // Construction
    public:
        CTestColorPoolDlg(CWnd* pParent = nullptr);    // standard constructor
    
    // Dialog Data
    #ifdef AFX_DESIGN_TIME
        enum { IDD = IDD_TESTCOLORPOOL_DIALOG };
    #endif
    
        protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    
    
    // Implementation
    protected:
        HICON m_hIcon;
    
        // Generated message map functions
        virtual BOOL OnInitDialog();
        afx_msg void OnPaint();
        afx_msg HCURSOR OnQueryDragIcon();
        DECLARE_MESSAGE_MAP()
    public:
        afx_msg void OnDestroy();
    };
    

    // TestColorPoolDlg.cpp
    
    BOOL CTestColorPoolDlg::GetImgStreams()
    {
        // get dialog's handle
        HWND hWnd = GetSafeHwnd(); 
        if (!hWnd)
            return FALSE;
    
        // pass handle to object of PrintCallback
        m_colorPool.SetWndHandle(hWnd);  
    
        // initializing 
        if (!m_colorPool.Init())   
            return FALSE;
    
        // Listening frames
        if (!m_colorPool.FrameListener())
            return FALSE;
    
        return TRUE;
    }
    

    BOOL CTestColorPoolDlg::OnInitDialog()
    {
        CDialogEx::OnInitDialog();
    
        // Set the icon for this dialog.  The framework does this automatically
        //  when the application's main window is not a dialog
        SetIcon(m_hIcon, TRUE);            // Set big icon
        SetIcon(m_hIcon, FALSE);        // Set small icon
    
        // TODO: Add extra initialization here
        if (!GetImgStreams())  // start working
            return FALSE;
        return TRUE;  // return TRUE  unless you set the focus to a control
    }
    

    void CTestColorPoolDlg::OnDestroy()
    {
        CDialogEx::OnDestroy();
    
        // TODO: Add your message handler code here
        m_colorPool.Close();   // release resource and device
    }
    

    回复 (0)

    举报
  • 发布于2021-04-16 01:53:27

    只看该作者 显示全部

    等了那么久还是没有答案,只好自己写个DEMO。不得不说体验性好差,真的有点伤脑筋。不知道还有没有同样和我一样LOW的朋友,在苦苦寻觅。。。

    回复 (0)

    举报
  • 发布于2021-04-16 11:37:38

    只看该作者 显示全部
    133****0812 发表于 2021-04-16 01:53:27

    等了那么久还是没有答案,只好自己写个DEMO。不得不说体验性好差,真的有点伤脑筋。不知道还有没有同样和我一样LOW的朋友,在苦苦寻觅。。。

    您好,请教一下,您现在遇到了什么问题, 希望我们提供什么帮助?

    回复 (0)

    举报
  • 发布于2021-04-16 15:08:06

    只看该作者 显示全部
    不爱唠叨的唐僧 发表于 2021-04-16 11:37:38

    您好,请教一下,您现在遇到了什么问题, 希望我们提供什么帮助?

    如何高效的读取视频帧?而不是这么低效的设置屏幕像素。网上找了好久,都没有找到合适的方法。大佬,您有空贴个demo呗

    回复 (0)

    举报
  • 发布于2021-04-16 16:05:45

    只看该作者 显示全部
    不爱唠叨的唐僧 发表于 2021-04-16 11:37:38

    您好,请教一下,您现在遇到了什么问题, 希望我们提供什么帮助?

    如何正确地将像素填入cv::Mat或者是使用API?

    回复 (0)

    举报
  • 发布于2021-04-16 18:02:06

    只看该作者 显示全部
    using namespace cv;
    void PrintCallback::AnalyzeFrame(HWND hWnd, const VideoFrameRef& frame)
    {
        RGB888Pixel* pColor = (RGB888Pixel*)frame.getData();
        int nRows = frame.getHeight();  // 获取帧以像素为单位的长度
        int nClos = frame.getWidth();   // 获取帧以像素为单位的宽度
        cv::Mat mat(nRows, nClos, CV_8UC3, Scalar(255, 255, 255));  // 定义矩阵
    
        switch (frame.getVideoMode().getPixelFormat())
        {
        case PIXEL_FORMAT_RGB888:
            for (int row = 0; row < mat.rows; row++)
            {
                Vec3b* pData = mat.ptr<Vec3b>(row);  // 获取行指针
                if (!pData) break;
    
                for (int col = 0; col < mat.cols; col++)
                {
                    COLORREF& d = (COLORREF&)pColor[row * nClos + col];  // 获取像素的颜色 RGB
                    BYTE b = GetBValue(d), g = GetGValue(d), r = GetRValue(d);
                    int nCnk = col * 3;
                    pData[nCnk + 0] = b;  // B
                    pData[nCnk + 1] = g;  // G
                    pData[nCnk + 2] = r;  // R
                }
            }
            cv::imshow("", mat);
            break;
        default:
            ::MessageBox(hWnd, L"Unknown format\n", _T("错误提示"), MB_OK);
            break;
        }
    }
    

    尝试了一次cv::Mat结果是颜色都偏蓝了。效率比直接setpixel还慢。。。。

    回复 (0)

    举报
  • 发布于2021-04-16 18:03:43

    只看该作者 显示全部
    133****0812 发表于 2021-04-16 16:05:45

    如何正确地将像素填入cv::Mat或者是使用API?

    using namespace cv;
    void PrintCallback::AnalyzeFrame(HWND hWnd, const VideoFrameRef& frame)
    {
        RGB888Pixel* pColor = (RGB888Pixel*)frame.getData();
        int nRows = frame.getHeight();  // 获取帧以像素为单位的长度
        int nClos = frame.getWidth();   // 获取帧以像素为单位的宽度
        cv::Mat mat(nRows, nClos, CV_8UC3, Scalar(255, 255, 255));  // 定义矩阵
    
        switch (frame.getVideoMode().getPixelFormat())
        {
        case PIXEL_FORMAT_RGB888:
            for (int row = 0; row < mat.rows; row++)
            {
                Vec3b* pData = mat.ptr<Vec3b>(row);  // 获取行指针
                if (!pData) break;
    
                for (int col = 0; col < mat.cols; col++)
                {
                    COLORREF& d = (COLORREF&)pColor[row * nClos + col];  // 获取像素的颜色 RGB
                    BYTE b = GetBValue(d), g = GetGValue(d), r = GetRValue(d);
                    int nCnk = col * 3;
                    pData[nCnk + 0] = b;  // B
                    pData[nCnk + 1] = g;  // G
                    pData[nCnk + 2] = r;  // R
                }
            }
            cv::imshow("", mat);
            break;
        default:
            ::MessageBox(hWnd, L"Unknown format\n", _T("错误提示"), MB_OK);
            break;
        }
    }
    

    不对呀,颜色偏蓝,效率更低了。难道要用古老的api了???

    回复 (0)

    举报
  • 发布于2021-04-16 20:55:41

    只看该作者 显示全部
    using namespace cv;
    void PrintCallback::AnalyzeFrame(HWND hWnd, const VideoFrameRef& frame)
    {
        RGB888Pixel* pColor = (RGB888Pixel*)frame.getData();
        int nRows = frame.getHeight();  // 获取帧以像素为单位的长度
        int nClos = frame.getWidth();   // 获取帧以像素为单位的宽度
        cv::Mat mat(nRows, nClos, CV_8UC3, Scalar(255, 255, 255));  // 定义矩阵  
        switch (frame.getVideoMode().getPixelFormat())
        {
        case PIXEL_FORMAT_RGB888:
            for (int row = 0; row < mat.rows; row++)
            {
                Vec3b* pData = mat.ptr<Vec3b>(row);  // 获取行指针
                if (!pData) break;
    
                for (int col = 0; col < mat.cols; col++)
                {
                    COLORREF& d = (COLORREF&)pColor[row * nClos + col];  // 获取像素的颜色 RGB
                    BYTE b = GetBValue(d), g = GetGValue(d), r = GetRValue(d);
    
                    int nCnk = col * 3;
                    pData[nCnk + 0] = b;  // B
                    pData[nCnk + 1] = g;  // G
                    pData[nCnk + 2] = r;  // R
                }
            }
    
            cv::rotate(mat, mat, ROTATE_90_CLOCKWISE);
            cv::imshow("", mat);
            break;
        default:
            ::MessageBox(hWnd, L"Unknown format\n", _T("错误提示"), MB_OK);
            break;
        }
    }
    

    回复 (0)

    举报
  • 发布于2021-04-16 23:26:46

    只看该作者 显示全部
    void PrintCallback::AnalyzeFrame(CTestColorPoolDlg* pDlg, const VideoFrameRef& frame)
    {
        int h = frame.getHeight();
        int w = frame.getWidth();
        RGB888Pixel* pColor = NULL;
    
        CClientDC dc(pDlg);
        CDC memDC;
        memDC.CreateCompatibleDC(&dc);
    
        CBitmap bmp;
        bmp.CreateCompatibleBitmap(&dc, h, w);
        memDC.SelectObject(&bmp);
    
        BITMAPINFO bmpInfo;
        bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmpInfo.bmiHeader.biWidth = h;
        bmpInfo.bmiHeader.biHeight = -w;
        bmpInfo.bmiHeader.biPlanes = 1;
        bmpInfo.bmiHeader.biBitCount = 24;
        bmpInfo.bmiHeader.biCompression = BI_RGB;
        bmpInfo.bmiHeader.biSizeImage = 0;
        bmpInfo.bmiHeader.biXPelsPerMeter = 3000;
        bmpInfo.bmiHeader.biYPelsPerMeter = 3000;
        bmpInfo.bmiHeader.biClrUsed = 0;
        bmpInfo.bmiHeader.biClrImportant = 0;
    
        long nLnBytes = (bmpInfo.bmiHeader.biWidth * 3 + 3) / 4 * 4;
        BYTE* pData = new BYTE[nLnBytes * abs(bmpInfo.bmiHeader.biHeight)];
    
        //清成黑色
        memset(pData, 0, nLnBytes * abs(bmpInfo.bmiHeader.biHeight));
        COLORREF ref[680];
        switch (frame.getVideoMode().getPixelFormat())
        {
        case PIXEL_FORMAT_RGB888:
            pColor = (RGB888Pixel*)frame.getData();  // get array' address of image that in pixels
            // traverses the pixels according to the height and width of the image
            for (int i = 0; i < h; i++)
            {
                for (int j = 0; j < w; j++)
                {
                    COLORREF& d = (COLORREF&)pColor[i * w + j];  // mandatory reference  3bytes? 4bytes? 
    
                    pData[i * nLnBytes + j * 3 + 1] = GetGValue(d);    //g
                    pData[i * nLnBytes + j * 3 + 2] = GetRValue(d);    //r
                    pData[i * nLnBytes + j * 3 + 3] = GetBValue(d);    //b
                }
            }
            SetDIBits(dc.m_hDC, bmp, 0, abs(bmpInfo.bmiHeader.biHeight), pData, &bmpInfo, DIB_RGB_COLORS);
            delete[]pData;
            dc.BitBlt(0, 0, bmpInfo.bmiHeader.biWidth, abs(bmpInfo.bmiHeader.biHeight), &memDC, 0, 0, SRCCOPY);
            break;
        default:
            ::MessageBox(pDlg->GetSafeHwnd(), L"Unknown format\n", _T("错误提示"), MB_OK);
            break;
        }
    }
    
    问题已经解决了,我不会OpenCV。只好用API来玩玩
    

    回复 (0)

    举报
  • 发布于2021-04-27 10:12:44

    只看该作者 显示全部
    void PrintCallback::onRender(const void* pData)
    {
        if (!pData)
            return;
    
        RGB888Pixel* pColor = (RGB888Pixel*)pData;
        cv::Mat& mat = theApp.getMatrix();
        int nRows = mat.rows;
        int nClos = mat.cols;   // 获取帧以像素为单位的宽度
        auto p = mat.data;
        for (int row = 0; row < nRows; row++)
        {
            for (int col = 0; col < nClos; col++)
            {
                COLORREF& d = (COLORREF&)pColor[row * nClos + col];  // 获取像素的颜色 RGB
                *p++ = GetBValue(d), *p++ = GetGValue(d), *p++ = GetRValue(d);
            }
        }
    
        if (!theApp.m_pMainWnd)
            return;
    
        theApp.m_pMainWnd->PostMessage(UM_TEST);
    }
    
    void PrintCallback::AnalyzeFrame(CTestColorPoolDlg* pDlg, const VideoFrameRef& frame)
    {
        switch (frame.getVideoMode().getPixelFormat())
        {
        case PIXEL_FORMAT_RGB888:
            onRender(frame.getData());
            break;
        default:
            ::MessageBox(pDlg->GetSafeHwnd(), L"Unknown format\n", _T("错误提示"), MB_OK);
            break;
        }
    }
    

    来个OpenCv的

    回复 (1)

    举报
  • 发布于2021-06-25 15:09:17

    只看该作者 显示全部

    再来一波。呵呵,啥也不是。

    /*
    说明:  
    用OpenNI2读取深度相机的深度和彩色流,并用OpenNI2自带的方法进行配准,每帧的画面用OpenCV显示出来。
    */
    #include      
    #include      
    #include      
    #include "OpenNI.h"     
    #include "opencv2/core/core.hpp"     
    #include "opencv2/highgui/highgui.hpp"     
    #include "opencv2/imgproc/imgproc.hpp"     
    using namespace std;
    using namespace cv;
    using namespace openni;
    
    void CheckOpenNIError(Status result, string status)
    {
        if (result != STATUS_OK)
            cerr << status << " Error: " << OpenNI::getExtendedError() << endl; } int main(int argc, char** argv) { Status result = STATUS_OK; //OpenNI2 image VideoFrameRef oniDepthImg; VideoFrameRef oniColorImg; //OpenCV image cv::Mat cvDepthImg; cv::Mat cvBGRImg; cv::Mat cvFusionImg; cv::namedWindow("depth"); cv::namedWindow("image"); cv::namedWindow("fusion"); char key = 0; // initialize OpenNI2 result = OpenNI::initialize(); CheckOpenNIError(result, "initialize context"); // open device Device device; result = device.open(openni::ANY_DEVICE); // create depth stream VideoStream oniDepthStream; result = oniDepthStream.create(device, openni::SENSOR_DEPTH); // set depth video mode VideoMode modeDepth; modeDepth.setResolution(640, 480); modeDepth.setFps(30); modeDepth.setPixelFormat(PIXEL_FORMAT_DEPTH_1_MM); oniDepthStream.setVideoMode(modeDepth); // start depth stream result = oniDepthStream.start(); // create color stream VideoStream oniColorStream; result = oniColorStream.create(device, openni::SENSOR_COLOR); // set color video mode VideoMode modeColor; modeColor.setResolution(640, 480); modeColor.setFps(30); modeColor.setPixelFormat(PIXEL_FORMAT_RGB888); oniColorStream.setVideoMode(modeColor); // set depth and color imge registration mode if (device.isImageRegistrationModeSupported(IMAGE_REGISTRATION_DEPTH_TO_COLOR)) { device.setImageRegistrationMode(IMAGE_REGISTRATION_DEPTH_TO_COLOR); } // start color stream result = oniColorStream.start(); while (key != 27) { // read frame if (oniColorStream.readFrame(&oniColorImg) == STATUS_OK) { // convert data into OpenCV type cv::Mat cvRGBImg(oniColorImg.getHeight(), oniColorImg.getWidth(), CV_8UC3, (void*)oniColorImg.getData()); cv::cvtColor(cvRGBImg, cvBGRImg, COLOR_RGB2BGR); // COLOR_RGB2GRAY cv::imshow("image", cvBGRImg); } if (oniDepthStream.readFrame(&oniDepthImg) == STATUS_OK) { cv::Mat cvRawImg16U(oniDepthImg.getHeight(), oniDepthImg.getWidth(), CV_16UC1, (void*)oniDepthImg.getData()); cvRawImg16U.convertTo(cvDepthImg, CV_8U, 255.0 / (oniDepthStream.getMaxPixelValue())); // convert depth image GRAY to BGR cv::cvtColor(cvDepthImg, cvFusionImg, COLOR_GRAY2BGR); cv::imshow("depth", cvDepthImg); } cv::addWeighted(cvBGRImg, 0.5, cvFusionImg, 0.5, 0, cvFusionImg); cv::imshow("fusion", cvFusionImg); key = cv::waitKey(20); } //cv destroy cv::destroyWindow("depth"); cv::destroyWindow("image"); cv::destroyWindow("fusion"); //OpenNI2 destroy oniDepthStream.destroy(); oniColorStream.destroy(); device.close(); OpenNI::shutdown(); return 0; } 

    回复 (2)

    举报
返回上级
共12条
跳至  页 
举报

请选择举报理由

  • 垃圾广告
  • 违规内容
  • 恶意灌水
  • 重复发帖
提示

奥比中光 · 3D视觉开发者社区...

站长统计