void onNewDepthSample(DepthNode node, DepthNode::NewSampleReceivedData data) { int32_t w, h; FrameFormat_toResolution(data.captureConfiguration.frameFormat,&w,&h); if ( data.depthMap != nullptr ) { Mat depth( h, w, CV_16SC1, (void*)(const int16_t*)data.depthMap ); Mat hsv( h, w, CV_8UC3); Mat psCol( h, w, CV_8UC3); namedWindow("color depth", 0); short level; for(int y=0; y<h; y++) { for(int x=0; x<w; x++) { level = depth.at<short>(y, x); if(level > 32000) { //invalid hsv.data[y * hsv.step + x*3 + 0] = 0; hsv.data[y * hsv.step + x*3 + 1] = 0; hsv.data[y * hsv.step + x*3 + 2] = 0; } else { uchar p = level%100; hsv.data[y * depth8u.step + x*3 + 0] = (uchar)(p*2.56); hsv.data[y * depth8u.step + x*3 + 1] = 255; hsv.data[y * depth8u.step + x*3 + 2] = 255; } } } cvtColor(hsv, psCol, CV_HSV2BGR_FULL); imshow("color depth", psCol); int c = waitKey( 10 ); if(c==27 || c=='q') g_context.quit(); if(c=='c') imwrite("DS325.png", psCol); } g_dFrames++; }
2012年11月16日金曜日
DepthSense SDKで距離画像を取得,OpenCVで表示
SoftkineticのDepthSense SDKで,DS325からの距離画像をOpenCVのMat(CV_16SC1)に放り込み,
100mmで色相が一周するように擬似カラー化して表示する.
2012年7月26日木曜日
OpenNIでキャプチャしてOpenCVで処理してC#で表示する
ASUSのXtionPRO LiveからRGB画像とDepth画像を取得し,
OpenCVでちょこっと処理し,結果をC#で表示するプログラム.
今回はC++で基本的な作業を行なうDLLを作成し,C#でGUI部分を作成する.
いろいろと無駄があるかもしれないけれど,とりあえず動くのでOK.
プロジェクトの共通プロパティ「参照」に「System.Drawing」と「XCapWrapper」を追加.
キャプチャした画像をBitmapにして返す.
参考サイト:C++/CLIで動かしているOpenCVのCvImageをC#.NETのBitmapオブジェクトにして読み込む
ここで取り出そうとするビットマップ画像の幅は,4の倍数じゃないとエラーが起こる.
OpenCVでちょこっと処理し,結果をC#で表示するプログラム.
今回はC++で基本的な作業を行なうDLLを作成し,C#でGUI部分を作成する.
- 基本DLL.OpenCVやOpenNIなどの外部ライブラリを使用する.
- プロジェクト名:XCapBase
- ソースファイル:XtionCaptureBase.cpp
- ヘッダファイル:XtionCaptureBase.h
- ラッパークラスDLLその1.C++として,1のライブラリをくるみ,入出力のみ行う.
- プロジェクト名:XCapWrapper
- ソースファイル:XCaptureWrapper.cpp
- ヘッダファイル:XCaptureWrapper.h
- ラッパークラスDLLその2.C++/CLIとして,2のライブラリをくるむ.C#から参照可能.
- プロジェクト名:XCWrapCLI
- ソースファイル:XCWrapCLI.cpp
- ヘッダファイル:XCWrapCLI.h
- C#のWindows Formプログラム.
- プロジェクト名:XtionCapture
いろいろと無駄があるかもしれないけれど,とりあえず動くのでOK.
XCapBase : 基本処理クラス
このクラスの中であれば,OpenCVやOpenNIの関数を自由に使える.
ただし,public 関数には,独自型を使わないようにしておく.
XtionCaptureBase.h
ただし,public 関数には,独自型を使わないようにしておく.
XtionCaptureBase.h
#ifdef XCAPBASE_EXPORTS #define XCB_DECLSPEC __declspec(dllexport) // DLLにexport #else #define XCB_DECLSPEC __declspec(dllimport) // DLLをimport #endif #include <XnCppWrapper.h> #include <opencv2/opencv.hpp> class XCB_DECLSPEC CXtionCaptureBase { public: CXtionCaptureBase(void); ~CXtionCaptureBase(void); void capture(int *w, int *h, char **rgb, char **dmap); private: xn::Context m_context; xn::ImageGenerator m_image; xn::DepthGenerator m_depth; cv::Mat m_RGBmat; cv::Mat m_Depthmat; };
XtionCaptureBase.cpp
#include "XtionCaptureBase.h" #pragma comment(lib,"openNI.lib") #ifdef _DEBUG #pragma comment (lib, "opencv_core242d.lib") #pragma comment (lib, "opencv_highgui242d.lib") #pragma comment (lib, "opencv_imgproc242d.lib") #else #pragma comment (lib, "opencv_core242.lib") #pragma comment (lib, "opencv_highgui242.lib") #pragma comment (lib, "opencv_imgproc242.lib") #endif using namespace xn; using namespace cv; CXtionCaptureBase::CXtionCaptureBase(void) { m_context.Init(); XnMapOutputMode mapMode; mapMode.nXRes = 640; mapMode.nYRes = 480; mapMode.nFPS = 30; m_image.Create(m_context); m_image.SetMapOutputMode(mapMode); m_depth.Create(m_context); m_depth.SetMapOutputMode(mapMode); m_context.StartGeneratingAll(); } CXtionCaptureBase::~CXtionCaptureBase(void) { } void CXtionCaptureBase::capture(int *w, int *h, char **rgb, char **dmap) { ImageMetaData imageMD; DepthMetaData depthMD; m_context.WaitAnyUpdateAll();//wait and error processing m_image.GetMetaData(imageMD); m_depth.GetMetaData(depthMD); m_depth.GetAlternativeViewPointCap().SetViewPoint(m_image); //Image Mat imageR(480, 640, CV_8UC3, (unsigned char*)imageMD.RGB24Data()); cvtColor(imageR, m_RGBmat, CV_RGB2BGR); //Depth Mat depth16(480, 640, CV_16UC1, (unsigned short*)depthMD.Data()); convertScaleAbs(depth16, m_Depthmat, 0.7, -300); //16bit -> 8bit *w = 640; *h = 480; *rgb = (char *)m_RGBmat.data; *dmap = (char *)m_Depthmat.data; }
XCapWrapper : C++のラッパークラス
プロジェクトの「参照」に,XCapBaseを追加する.
XCapWrapper.h
XCapWrapper.h
#ifdef XCAPWRAPPER_EXPORTS #define XCW_DECLSPEC __declspec(dllexport) // DLLにexport #else #define XCW_DECLSPEC __declspec(dllimport) // DLLをimport #endif class XCW_DECLSPEC CXCaptureWrapper { public: CXCaptureWrapper(void); ~CXCaptureWrapper(void); void capture(int *w, int *h, char **rgb, char **dmap); };
XCapWrapper.cpp
#include "XCaptureWrapper.h" #include "../XCapBase/XtionCaptureBase.h" CXtionCaptureBase *cxcb; CXCaptureWrapper::CXCaptureWrapper(void) { cxcb = new CXtionCaptureBase(); } CXCaptureWrapper::~CXCaptureWrapper(void) { delete cxcb; } void CXCaptureWrapper::capture(int *w, int *h, char **rgb, char **dmap) { cxcb->capture(w, h, rgb, dmap); }
XCWrapCLI : C++/CLIのラッパークラス
「構成プロパティ」の「全般」で共通言語ランタイムサポート(/clr)を選択する.プロジェクトの共通プロパティ「参照」に「System.Drawing」と「XCapWrapper」を追加.
キャプチャした画像をBitmapにして返す.
参考サイト:C++/CLIで動かしているOpenCVのCvImageをC#.NETのBitmapオブジェクトにして読み込む
ここで取り出そうとするビットマップ画像の幅は,4の倍数じゃないとエラーが起こる.
XCWrapCLI.h
#pragma once using namespace System::Drawing; namespace XCWrapper { public ref class XCWrapCLI { public: XCWrapCLI(void); void capture(void); System::Drawing::Bitmap^ getBitmap(void); System::Drawing::Bitmap^ getDepthmap(void); private: System::Drawing::Bitmap^ bitmap; System::Drawing::Bitmap^ depthmap; }; }
XCWrapCLI.cpp
#include "XCWrapCLI.h" #include "../XCapWrapper/XCaptureWrapper.h" namespace XCWrapper { CXCaptureWrapper *xcap; XCWrapCLI::XCWrapCLI(void) { xcap = new CXCaptureWrapper(); } void XCWrapCLI::capture() { int w, h; char *prgb, *pdmap; xcap->capture(&w, &h, &prgb, &pdmap); //RGB Image this->bitmap = dynamic_cast<System::Drawing::Bitmap^>( gcnew System::Drawing::Bitmap(w, h, w*3, System::Drawing::Imaging::PixelFormat::Format24bppRgb, static_cast<System::IntPtr>(prgb))); //DepthMap this->depthmap = dynamic_cast<System::Drawing::Bitmap^>( gcnew System::Drawing::Bitmap(w, h, w, System::Drawing::Imaging::PixelFormat::Format8bppIndexed, static_cast<System::IntPtr>(pdmap))); System::Drawing::Imaging::ColorPalette^ pal = this->depthmap->Palette; for(int i=0; i<256; i++) pal->Entries[i] = Color::FromArgb(255,i,i,i); this->depthmap->Palette = pal; } System::Drawing::Bitmap^ XCWrapCLI::getBitmap(void) { return this->bitmap; } System::Drawing::Bitmap^ XCWrapCLI::getDepthmap(void) { return this->depthmap; } }
XtionCapture : C#のプログラム
スタートボタンを押すと,キャプチャ画像を(スレッドを使って)表示する.
mainForm.cs
mainForm.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; using XCWrapper; namespace XtionCapture { public partial class mainForm : Form { private Thread trd; private bool moveFlag; XCWrapCLI xcap; public mainForm() { InitializeComponent(); moveFlag = false; xcap = new XCWrapCLI(); } private void mainForm_Load(object sender, EventArgs e) { trd = new Thread(new ThreadStart(this.ThreadTask)); trd.IsBackground = true; trd.Start(); } private void ThreadTask() { while (true) { if (moveFlag) { xcap.capture(); pictureBox1.Image = xcap.getBitmap(); pictureBox2.Image = xcap.getDepthmap(); } Thread.Sleep(30); } } private void StartButton_Click(object sender, EventArgs e) { moveFlag = true; } private void StopButton_Click(object sender, EventArgs e) { moveFlag = false; } } }
ラベル:
OpenCV
登録:
投稿 (Atom)