Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Creative Senz3D camera using Intel Perceptual Computing SDK. #60

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ Your use of the library may involve use of the Microsoft Kinect for Windows Soft
which is currently subject to the following license:
http://www.microsoft.com/en-us/kinectforwindows/develop/sdk-eula.aspx

Your use of the library may involve use of the Intel Perceptual Computing SDK 2013,
which is currently subject to the following license:
http://software.intel.com/sites/products/vcsource/files/Intel_PCSDK_EULA.rtf
11 changes: 11 additions & 0 deletions OpenNI.sln
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PSLink", "Source\Drivers\PS
{72D595BB-8C52-449B-91DB-0E9F6AEAF5BB} = {72D595BB-8C52-449B-91DB-0E9F6AEAF5BB}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PerCDevice", "Source\Drivers\PerCDevice\PerCDevice.vcxproj", "{D7E18C47-5E29-4D56-9C5B-57F7765F7B61}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Expand Down Expand Up @@ -300,6 +302,14 @@ Global
{5B74F010-8B79-46B5-B906-C2B56CDB3386}.Release|x64.Build.0 = Release|x64
{5B74F010-8B79-46B5-B906-C2B56CDB3386}.Release|x86.ActiveCfg = Release|Win32
{5B74F010-8B79-46B5-B906-C2B56CDB3386}.Release|x86.Build.0 = Release|Win32
{D7E18C47-5E29-4D56-9C5B-57F7765F7B61}.Debug|x64.ActiveCfg = Debug|x64
{D7E18C47-5E29-4D56-9C5B-57F7765F7B61}.Debug|x64.Build.0 = Debug|x64
{D7E18C47-5E29-4D56-9C5B-57F7765F7B61}.Debug|x86.ActiveCfg = Debug|Win32
{D7E18C47-5E29-4D56-9C5B-57F7765F7B61}.Debug|x86.Build.0 = Debug|Win32
{D7E18C47-5E29-4D56-9C5B-57F7765F7B61}.Release|x64.ActiveCfg = Release|x64
{D7E18C47-5E29-4D56-9C5B-57F7765F7B61}.Release|x64.Build.0 = Release|x64
{D7E18C47-5E29-4D56-9C5B-57F7765F7B61}.Release|x86.ActiveCfg = Release|Win32
{D7E18C47-5E29-4D56-9C5B-57F7765F7B61}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -319,6 +329,7 @@ Global
{15ECC029-90DE-4D1D-B00A-4A8E647D8C24} = {238D091D-1A85-4A61-9DCD-483768C51804}
{E636BACA-795F-41CF-BC52-14C727BF014E} = {238D091D-1A85-4A61-9DCD-483768C51804}
{5B74F010-8B79-46B5-B906-C2B56CDB3386} = {238D091D-1A85-4A61-9DCD-483768C51804}
{D7E18C47-5E29-4D56-9C5B-57F7765F7B61} = {238D091D-1A85-4A61-9DCD-483768C51804}
{BDA3BF24-550A-4BF9-83E5-0056134EED40} = {20285393-1DB1-4300-8AD3-30AEAE3C5DA6}
{D39A4248-3985-41DE-AFD5-AEC58D29291F} = {20285393-1DB1-4300-8AD3-30AEAE3C5DA6}
{D5709FB9-909D-415F-8F86-2F25BEF6CE23} = {20285393-1DB1-4300-8AD3-30AEAE3C5DA6}
Expand Down
2 changes: 2 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Windows
From: http://msdn.microsoft.com/en-us/vstudio/bb984878.aspx
- Microsoft Kinect SDK v1.6
From: http://go.microsoft.com/fwlink/?LinkID=262831
- Intel (R) Perceptual Computing SDK 2013
From: http://registrationcenter-download.intel.com/akdlm/irc_nas/3581/intel_pc_sdk_websetup_11066.exe
- Python 2.6+/3.x
From: http://www.python.org/download/
- PyWin32
Expand Down
2 changes: 1 addition & 1 deletion Samples/ClosestPointViewer/Viewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ void SampleViewer::display()

for (int x = 0; x < width; ++x, ++pDepth, ++pTex)
{
if (*pDepth != 0)
if ((*pDepth != 0) && (*pDepth < 10000))
{
if (*pDepth == closest.Z)
{
Expand Down
2 changes: 1 addition & 1 deletion Samples/Common/OniSampleUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ void calculateHistogram(float* pHistogram, int histogramSize, const openni::Vide
{
for (int x = 0; x < width; ++x, ++pDepth)
{
if (*pDepth != 0)
if ((*pDepth != 0) && ((*pDepth) < histogramSize))
{
pHistogram[*pDepth]++;
nNumberOfPoints++;
Expand Down
2 changes: 1 addition & 1 deletion Samples/SimpleViewer/Viewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ void SampleViewer::display()

for (int x = 0; x < m_depthFrame.getWidth(); ++x, ++pDepth, ++pTex)
{
if (*pDepth != 0)
if ((*pDepth != 0) && (*pDepth < MAX_DEPTH))
{
int nHistValue = m_pDepthHist[*pDepth];
pTex->r = nHistValue;
Expand Down
194 changes: 194 additions & 0 deletions Source/Drivers/PerCDevice/PerCBaseStream.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
#include "PerCDeviceEnumerator.h"
#include "PerCBaseStream.h"

namespace perc_device
{
PerCBaseStream::PerCBaseStream(XnUInt32 idxDeviceInternal, XnUInt32 idxStream, const OniVideoMode &videoMode)
: m_idxDeviceInternal(idxDeviceInternal)
, m_pxcDevice(NULL)
, m_idxStream(idxStream)
, m_pxcStream(NULL)
, m_running(false)
, m_mirror(false)
, m_videoMode(videoMode)
{
m_cropping.enabled = 0;
createStream();
}

PerCBaseStream::~PerCBaseStream()
{
stop();
}

OniStatus PerCBaseStream::start()
{
if (m_running)
return ONI_STATUS_OK;

if (!m_pxcStream.IsValid())
return ONI_STATUS_ERROR;

PXCCapture::VideoStream::ProfileInfo pinfo;
for (int idxProfile = 0; ; idxProfile++)
{
if (PXC_STATUS_NO_ERROR > m_pxcStream->QueryProfile(idxProfile, &pinfo))
return ONI_STATUS_ERROR;
if ((m_videoMode.resolutionX == (int)pinfo.imageInfo.width) && (m_videoMode.resolutionY == (int)pinfo.imageInfo.height) &&
(pinfo.frameRateMin.denominator * m_videoMode.fps >= pinfo.frameRateMin.numerator) &&
(pinfo.frameRateMax.denominator * m_videoMode.fps <= pinfo.frameRateMax.numerator))
break;
}
if (PXC_STATUS_NO_ERROR > m_pxcStream->SetProfile(&pinfo))
return ONI_STATUS_ERROR;

xnOSCreateThread(threadFunc, this, &m_threadHandle);

return ONI_STATUS_OK;
}

void PerCBaseStream::stop()
{
if (!m_running)
return;
m_running = false;
if (m_threadHandle)
xnOSWaitForThreadExit(m_threadHandle, 10000);

// Is there another way to stop stream?
// If we don't recreate device, a error may appears (or may not), then we change
// a stream profile on the running stream and then read a frame.
// Another way - set Sleep(1000) in start() after SetProfile() before start the thread
m_pxcStream.ReleaseRef();
m_pxcDevice.ReleaseRef();
createStream();
}

OniBool PerCBaseStream::isPropertySupported(int propertyId)
{
return ((ONI_STREAM_PROPERTY_VIDEO_MODE == propertyId) ||
(ONI_STREAM_PROPERTY_MIRRORING == propertyId) ||
(ONI_STREAM_PROPERTY_CROPPING == propertyId));
}
OniStatus PerCBaseStream::getProperty(int propertyId, void* data, int* pDataSize)
{
if (ONI_STREAM_PROPERTY_VIDEO_MODE == propertyId)
{
if (*pDataSize != sizeof(OniVideoMode))
{
printf("Unexpected size: %d != %d\n", *pDataSize, (int)sizeof(OniVideoMode));
return ONI_STATUS_ERROR;
}
return GetVideoMode((OniVideoMode*)data);
}
else if (ONI_STREAM_PROPERTY_MIRRORING == propertyId)
{
if (*pDataSize != sizeof(OniBool))
{
printf("Unexpected size: %d != %d\n", *pDataSize, (int)sizeof(OniBool));
return ONI_STATUS_ERROR;
}
*(OniBool *)data = m_mirror;
return ONI_STATUS_OK;
}
else if (ONI_STREAM_PROPERTY_CROPPING == propertyId)
{
if (*pDataSize != sizeof(OniCropping))
{
printf("Unexpected size: %d != %d\n", *pDataSize, (int)sizeof(OniCropping));
return ONI_STATUS_ERROR;
}
*(OniCropping *)data = m_cropping;
return ONI_STATUS_OK;
}
return ONI_STATUS_NOT_IMPLEMENTED;
}

OniStatus PerCBaseStream::setProperty(int propertyId, const void* data, int dataSize)
{
if (ONI_STREAM_PROPERTY_VIDEO_MODE == propertyId)
{
if (dataSize != sizeof(OniVideoMode))
{
printf("Unexpected size: %d != %d\n", dataSize, (int)sizeof(OniVideoMode));
return ONI_STATUS_ERROR;
}
return SetVideoMode((OniVideoMode*)data);
}
else if (ONI_STREAM_PROPERTY_MIRRORING == propertyId)
{
if (dataSize != sizeof(OniBool))
{
printf("Unexpected size: %d != %d\n", dataSize, (int)sizeof(OniBool));
return ONI_STATUS_ERROR;
}
m_mirror = *(const OniBool *)data;
return ONI_STATUS_OK;
}
else if (ONI_STREAM_PROPERTY_CROPPING == propertyId)
{
if (dataSize != sizeof(OniCropping))
{
printf("Unexpected size: %d != %d\n", dataSize, (int)sizeof(OniCropping));
return ONI_STATUS_ERROR;
}
m_cropping = *(OniCropping *)data;
return ONI_STATUS_OK;
}
return ONI_STATUS_NOT_IMPLEMENTED;
}

OniBool PerCBaseStream::getFrameRect(int &left, int &top, int &right, int &bottom)
{
left = 0; right = m_videoMode.resolutionX - 1;
top = 0; bottom = m_videoMode.resolutionY - 1;
if (0 == m_cropping.enabled)
return 1;

top = min(m_cropping.originY, m_cropping.originY + m_cropping.height - 1);
bottom = max(m_cropping.originY, m_cropping.originY + m_cropping.height - 1);
if ((bottom < 0) || (m_videoMode.resolutionY <= top))
return 0;
if (top < 0)
top = 0;
if (m_videoMode.resolutionY <= bottom)
bottom = m_videoMode.resolutionY - 1;

left = min(m_cropping.originX, m_cropping.originX + m_cropping.width - 1);
right = max(m_cropping.originX, m_cropping.originX + m_cropping.width - 1);
if ((right < 0) || (m_videoMode.resolutionX <= left))
return 0;
if (left < 0)
left = 0;
if (m_videoMode.resolutionX <= right)
right = m_videoMode.resolutionX - 1;

return 1;
}

void PerCBaseStream::createStream()
{
m_pxcDevice = deviceEnumerator().getDevice(m_idxDeviceInternal);
if (!m_pxcDevice.IsValid())
{
//TODO log
return;
}
if (PXC_STATUS_NO_ERROR > m_pxcDevice->CreateStream<PXCCapture::VideoStream>(m_idxStream, &m_pxcStream))
{
//TODO log
return;
}
}

XN_THREAD_PROC PerCBaseStream::threadFunc(XN_THREAD_PARAM pThreadParam)
{
PerCBaseStream* pStream = (PerCBaseStream*)pThreadParam;
pStream->m_running = true;
pStream->Mainloop();

XN_THREAD_PROC_RETURN(XN_STATUS_OK);
}


}//namespace perc_device
62 changes: 62 additions & 0 deletions Source/Drivers/PerCDevice/PerCBaseStream.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#ifndef _PERC_BASE_STREAM_H_
#define _PERC_BASE_STREAM_H_

#include "Driver/OniDriverAPI.h"
#include "XnLib.h"
#include "XnHash.h"
#include "XnEvent.h"
#include "XnPlatform.h"

#include "pxcsmartptr.h"
#include "pxccapture.h"

namespace perc_device
{
class PerCBaseStream
: public oni::driver::StreamBase
{
public:
PerCBaseStream(XnUInt32 idxDeviceInternal, XnUInt32 idxStream, const OniVideoMode &videoMode);
virtual ~PerCBaseStream();

bool isValid()
{
return (m_pxcDevice.IsValid() && m_pxcStream.IsValid());
}

virtual OniStatus start();
virtual void stop();

virtual OniStatus SetVideoMode(OniVideoMode*) = 0;
virtual OniStatus GetVideoMode(OniVideoMode* pVideoMode) = 0;

virtual OniBool isPropertySupported(int /*propertyId*/);
virtual OniStatus getProperty(int propertyId, void* data, int* pDataSize);
virtual OniStatus setProperty(int propertyId, const void* data, int dataSize);

virtual void Mainloop() = 0;
protected:
static XN_THREAD_PROC threadFunc(XN_THREAD_PARAM pThreadParam);
protected:
XnUInt32 m_idxDeviceInternal;
PXCSmartPtr<PXCCapture::Device> m_pxcDevice;
XnUInt32 m_idxStream;
PXCSmartPtr<PXCCapture::VideoStream> m_pxcStream;

void createStream();

bool m_running;
XN_THREAD_HANDLE m_threadHandle;
protected:
OniVideoMode m_videoMode;

OniBool m_mirror;
OniCropping m_cropping;
OniBool getFrameRect(int &left, int &top, int &right, int &bottom);
private:
PerCBaseStream(const PerCBaseStream &);
PerCBaseStream &operator =(const PerCBaseStream &);
};
}// namespace perc_device

#endif //_PERC_BASE_STREAM_H_
Loading