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
2011年8月5日金曜日
OpenCVの関数を使って連立方程式を解く
未知数が3つの3元連立方程式
2a + 2b + 3c = 15
3a + 5b + 2c = 19
5a + 3b + 3c = 20
OpenCVのMatの逆行列を計算する関数を使って,
ちゃんと,a=1, b=2, c=3の解が出る.
2a + 2b + 3c = 15
3a + 5b + 2c = 19
5a + 3b + 3c = 20
OpenCVのMatの逆行列を計算する関数を使って,
#include <opencv2/opencv.hpp>
using namespace cv;
using std::cout;
using std::endl;
int main()
{
Mat matA = (Mat_<float>(3,3) << 2, 2, 3, 3, 5, 2, 5, 3, 3);
Mat matB = (Mat_<float>(3,1) << 15, 19, 20);
Mat matX(3, 1, CV_32FC1);
matX = matA.inv()*matB;
cout << "a=" << matX.at<float>(0) << endl;
cout << "b=" << matX.at<float>(1) << endl;
cout << "c=" << matX.at<float>(2) << endl;
}
ちゃんと,a=1, b=2, c=3の解が出る.
ラベル:
OpenCV
2011年7月28日木曜日
OpenCV C++ ヒストグラムクラス
OpenCV2.X向けのヒストグラムクラス。
1Dとカラーのやつは「OpenCV 2 Computer Vision Application Programming Cookbook」に載っているやつ。これを基に、2次元ヒストグラム画像作成など自分なりに手を入れているけれど、まだ中途半端。
呼び出す側のソース例。
1Dとカラーのやつは「OpenCV 2 Computer Vision Application Programming Cookbook」に載っているやつ。これを基に、2次元ヒストグラム画像作成など自分なりに手を入れているけれど、まだ中途半端。
#include <opencv2/opencv.hpp>
class Histogram1D {
private:
int histSize[1];
float hranges[2];
const float* ranges[1];
int channels[1];
public:
Histogram1D(int hsize = 256) {
histSize[0] = hsize; //number of bins
hranges[0] = 0.0; //min pixel value
hranges[1] = 255.0; //max pixel value
ranges[0] = hranges;
channels[0] = 0; //by default, we lookup channel 0
}
void setHistSize(int hsize) {
histSize[0] = hsize;
}
void setRanges(float min, float max) {
hranges[0] = min;
hranges[1] = max;
ranges[0] = hranges;
if(max-min<histSize[0]) {
histSize[0] = (int)(max-min);
}
}
cv::MatND getHistogram(const cv::Mat &image, int ch = 0) {
cv::MatND hist;
channels[0] = ch;
cv::calcHist(&image, 1, channels, cv::Mat(), hist, 1, histSize, ranges);
return hist;
}
cv::Mat getHistogramImage(const cv::Mat &image, int channel = 0) {
cv::MatND hist= getHistogram(image, channel);
double maxVal = 0;
double minVal = 0;
cv::minMaxLoc(hist, &minVal, &maxVal, 0, 0);
cv::Mat histImg(histSize[0], histSize[0], CV_8U, cv::Scalar(255));
int hpt = static_cast<int>(0.9*histSize[0]);
for(int h=0; h<histSize[0]; h++) {
float binVal = hist.at<float>(h);
int intensity = static_cast<int>(binVal*hpt/maxVal);
cv::line(histImg, cv::Point(h,histSize[0]), cv::Point(h,histSize[0]-intensity), cv::Scalar::all(0));
}
return histImg;
}
};
class Histogram2D {
private:
int histSize[2];
float hranges[2];
const float* ranges[2];
int channels[2];
public:
Histogram2D(int h1size=256, int h2size = 256) {
histSize[0] = h1size;
histSize[1] = h2size;
hranges[0] = 0.0;
hranges[1] = 255.0;
ranges[0] = hranges;
ranges[1] = hranges;
channels[0] = 0;
channels[1] = 1;
}
cv::MatND getHistogram(const cv::Mat &img1, const cv::Mat &img2) {
cv::Mat planes[2];
img1.copyTo(planes[0]);
img2.copyTo(planes[1]);
cv::MatND hist;
cv::calcHist(planes, 2, channels, cv::Mat(), hist, 2, histSize, ranges);
return hist;
}
cv::Mat getHistogramImage(const cv::Mat &img1, const cv::Mat &img2) {
cv::MatND hist= getHistogram(img1, img2);
double maxVal = 0;
double minVal = 0;
cv::minMaxLoc(hist, &minVal, &maxVal, 0, 0);
cv::Mat histImg(histSize[0], histSize[1], CV_8U, cv::Scalar(0));
for(int h=0; h<histSize[0]; h++) {
for(int i=0; i<histSize[1]; i++) {
float binVal = hist.at<float>(h,i);
uchar intensity = static_cast<uchar>(binVal*255/maxVal);
histImg.at<uchar>(h,i) = intensity;
}
}
return histImg;
}
};
class ColorHistogram {
private:
int histSize[3];
float hranges[2];
const float* ranges[3];
int channels[3];
public:
ColorHistogram(int hSize = 256) {
histSize[0] = histSize[1] = histSize[2] = hSize;
hranges[0] = 0.0;
hranges[1] = 255.0;
ranges[0] = hranges;
ranges[1] = hranges;
ranges[2] = hranges;
channels[0] = 0;
channels[1] = 1;
channels[2] = 2;
}
cv::MatND getHistogram(const cv::Mat &image) {
cv::MatND hist;
cv::calcHist(&image, 1, channels, cv::Mat(), hist, 3, histSize, ranges);
return hist;
}
cv::SparseMat getSparseHistogram(const cv::Mat &image) {
cv::SparseMat hist(3, histSize, CV_32F);
cv::calcHist(&image, 1, channels, cv::Mat(), hist, 3, histSize, ranges);
return hist;
}
};
呼び出す側のソース例。
#include <opencv2/opencv.hpp>
#include "histogram.hpp"
#ifdef _DEBUG
#pragma comment(lib,"opencv_core230d.lib")
#pragma comment(lib,"opencv_highgui230d.lib")
#pragma comment(lib,"opencv_imgproc230d.lib")
#else
#pragma comment(lib,"opencv_core230.lib")
#pragma comment(lib,"opencv_highgui230d.lib")
#pragma comment(lib,"opencv_imgproc230d.lib")
#endif
using namespace cv;
using std::cout;
using std::endl;
int main()
{
//モノクロ画像のヒストグラム表示
Mat gray_img = imread("d:/test1.bmp", 0);
imshow("gray", gray_img);
Histogram1D h1(256);
imshow("Histogram", h1.getHistogramImage(gray_img));
//カラー画像のチャネル別ヒストグラム画像表示j
Mat cimg = imread("d:/test2.bmp");
imshow("color", cimg);
imshow("B", h1.getHistogramImage(cimg));
imshow("G", h1.getHistogramImage(cimg, 1));
imshow("R", h1.getHistogramImage(cimg, 2));
Mat hsvImg;
cvtColor(cimg, hsvImg, CV_BGR2HSV_FULL);
imshow("H", h1.getHistogramImage(hsvImg, 0));
imshow("S", h1.getHistogramImage(hsvImg, 1));
imshow("V", h1.getHistogramImage(hsvImg, 2));
//h1.setRanges(0.0, 180.0);
//imshow("H", h1.getHistogramImage(hsvImg));
//2チャンネル2次元ヒストグラム画像表示
std::vector<cv::Mat> planes;
cv::split(cimg, planes);
Histogram2D h2(128,128);
imshow("2Dhist", h2.getHistogramImage(planes[0], planes[1]));
//各ヒストグラムを得る。
MatND hist1 = h1.getHistogram(gray_img);
MatND hist2 = h2.getHistogram(planes[0], planes[1]);
//cout << hist2 << endl;
waitKey();
}
ラベル:
OpenCV
2011年7月15日金曜日
cv::MatのXMLファイルへの入出力
Matの内容をXML形式でファイルに出力 or ファイルから入力する方法のメモ.
2種類のMatを出力するプログラム
出力されたxmlファイルの中身.
読み込む方のプログラム
2種類のMatを出力するプログラム
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
Mat matA = (cv::Mat_<double>(3,3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);
Mat matB = cv::Mat::ones(5, 5, CV_8U)*3;
FileStorage cvfs("D:/test.xml", CV_STORAGE_WRITE);
write(cvfs,"matA", matA);
write(cvfs,"matB", matB);
}出力されたxmlファイルの中身.
<?xml version="1.0"?> <opencv_storage> <matA type_id="opencv-matrix"> <rows>3</rows> <cols>3</cols> <dt>d</dt> <data> 1. 0. 0. 0. 1. 0. 0. 0. 1.</data></matA> <matB type_id="opencv-matrix"> <rows>5</rows> <cols>5</cols> <dt>u</dt> <data> 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3</data></matB> </opencv_storage>
読み込む方のプログラム
int main()
{
Mat ma, mb;
FileStorage cvfs("D:/test.xml", CV_STORAGE_READ);
FileNode node(cvfs.fs, NULL);
read(node["matB"], mb);
read(node["matA"], ma);
std::cout << ma << std::endl;
std::cout << mb << std::endl;
}
ラベル:
OpenCV
2011年7月14日木曜日
OpenCV2.3向けのVisualStudio2010プロパティシート
VisualStudio2010のプロパティシートで,OpenCV2.3向けの設定.
- 解凍したwindows用バイナリ(OpenCV-2.3.0-win-superpack.exe)を「C:\OpenCV2.3」に配置
- プラットフォームが「Win32(x86)」の場合,C:\Users\(ユーザー名)\AppData\Local\Microsoft\MSBuild\v4.0 のMicrosoft.Cpp.Win32.user.props を下記の通り編集.
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ExecutablePath>C:\OpenCV2.3\build\bin;C:\OpenCV2.3\build\x86\vc10\bin;$(ExecutablePath)</ExecutablePath>
<IncludePath>C:\OpenCV2.3\build\include;$(IncludePath)</IncludePath>
<LibraryPath>C:\OpenCV2.3\build\x86\vc10\lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
</Project>対象プラットフォームがx64の場合には,Microsoft.Cpp.x64.user.propsを編集し,上記x86をx64に置き換えれば良い.
ラベル:
OpenCV
登録:
投稿 (Atom)