initializing an openni::VideoStream object without kinect plugged in - c++

I'm using openNI2 in order to capture kinect depth data.
in order to initialize m_depth, i have to use some methods of the class openni::VideoStream, like this:
openni::VideoStream m_depth;
openni::Device device;
const char* device_uri;
openni::Status ret;
device_uri = openni::ANY_DEVICE;
ret = openni::STATUS_OK;
ret = openni::OpenNI::initialize();
ret = device.open(device_uri);
ret = m_depth.create(device, openni::SENSOR_DEPTH);
The is that i want to initialize the object "m_depth" without the kinect plugged in. of course i can't because the methods of this class, like "m_depth.create" doesn't work.
There is a way to do that?

You can try using an .ONI file (a dummy could work) to init
Quoting the OpenNI2 documentation
Later, this file can be used to initialize a file Device, and used to
play back the same data that was recorded.
Opening a file device is done by passing its path as the uri to the
Device::open() method
So, you can change this line
device_uri = openni::ANY_DEVICE;
to the path of the dummy ONI file...
I don't think in OpenNI2 there is another way to create a depth stream, and actually it doesn't make sense to create a stream without a camera unless you want to use the coordinate converter class...
In openni 1.x you can try using mockdepth (though I didn't managed to make it work correctly)

Related

Get raw buffer for in-memory dataset in GDAL C++ API

I have generated a GeoTiff dataset in-memory using GDALTranslate() with a /vsimem/ filepath. I need access to the buffer for the actual GeoTiff file to put it in a stream for an external API. My understanding is that this should be possible with VSIGetMemFileBuffer(), however I can't seem to get this to return anything other than nullptr.
My code is essentially as follows:
//^^ GDALDataset* srcDataset created somewhere up here ^^
//psOptions struct has "-b 4" and "-of GTiff" settings.
const char* filep = "/vsimem/foo.tif";
GDALDataset* gtiffData = GDALTranslate(filep, srcDataset, psOptions, nullptr);
vsi_l_offset size = 0;
GByte* buf = VSIGetMemFileBuffer(filep, &size, true); //<-- returns nullptr
gtiffData seems to be a real dataset on inspection, it has all the appropriate properties (number of bands, raster size, etc). When I provide a real filesystem location to GDALTranslate() rather than the /vsimem/ path and load it up in QGIS it renders correctly too.
Looking a the source for VSIGetMemFileBuffer(), this should really only be returning nullptr if the file can't be found. This suggests i'm using it incorrectly. Does anyone know what the correct usage is?
Bonus points: Is there a better way to do this (stream the file out)?
Thanks!
I don't know anything about the C++ API. But in Python, the snippet below is what I sometimes use to get the contents of an in-mem file. In my case mainly VRT's but it shouldn't be any different for other formats.
But as said, I don't know if the VSI-api translate 1-on-1 to C++.
from osgeo import gdal
filep = "/vsimem/foo.tif"
# get the file size
stat = gdal.VSIStatL(filep, gdal.VSI_STAT_SIZE_FLAG)
# open file
vsifile = gdal.VSIFOpenL(filep, 'r')
# read entire contents
vsimem_content = gdal.VSIFReadL(1, stat.size, vsifile)
In the case of a VRT the content would be text, shown with something like print(vsimem_content.decode()). For a tiff it would of course be binary data.
I came back to this after putting in a workaround, and upon swapping things back over it seems to work fine. #mmomtchev suggested looking at the CPL_DEBUG output, which showed nothing unusual (and was silent during the actual VSIGetMemFileBuffer call).
In particular, for other reasons I had to put a GDALWarp call in between calling GDALTranslate and accessing the buffer, and it seems that this is what makes the difference. My guess is that GDALWarp is calling VSIFOpenL internally - although I can't find this in the source - and this does some kind of initialisation for VSIGetMemFileBuffer. Something to try for anyone else who encounters this.

Trying to encode a GIF file using giflib

I am given image data and color table I am trying to export it as a single frame GIF using giflib. I looked into the API, but can't get it to work. The program crashes even at the first function:
GifFileType image_out;
int errorCode = 0;
char* fileName = "SomeName.gif";
image_out = *EGifOpenFileName(fileName,true, &errorCode);
It is my understanding that I first need to open a file by specifying it's name and then update it with fileHandle. Then Fill in the screen description, the extension block the image data and add the 3B ending to the file. Then use EGifSpew to export the whole gif. The problem is that I can't even use EGifOpenFileName(); The program crashes at that line.
Can someone help me the API of giflib? This problem is getting really frustrating.
Thanks.
EDIT:
For the purposes of simple encoding I do not want to specify a color table and I just want to encode a single frame GIF.
The prototype is:
GifFileType *EGifOpenFileName(char *GifFileName, bool GifTestExistance, int *ErrorCode)
You should write as
GifFileType* image_out = EGifOpenFileName(fileName,true, &errorCode);
Note GifFileType is not POD type so you should NOT copy like that.

OpenNI2: Reading in .oni Recording

I was hoping someone could provide some direction on how I could go about reading in a previously recording .ONI file generated using OpenNI2. The current path that I'm on suggested that I pass my file in to the device and that it could handle the file and read from it instead of the camera. Something like:
Device device
rc = device.open("C:/Somefolder/depth.oni");
Currently any variation of this simply fails to load a device. Any suggestions are always much appreciated!
you can do the following assuming you have file_name which is a string:
//all variables needed
openni::Device device_;
openni::VideoStream ir_;
openni::VideoStream color_;
openni::Status rc_;
openni::VideoFrameRef irf_;
openni::VideoFrameRef colorf_;
openni::OpenNI::initialize ();
const char *cstr = file_name.c_str();
device_.open(cstr);
ir_.create (device_, openni::SENSOR_DEPTH);
ir_.start ();
device_.setImageRegistrationMode (openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR);
color_.create (device_, openni::SENSOR_COLOR);
color_.start ();
ir_.readFrame (&irf_);
color_.readFrame (&colorf_);
The last two functions read the depth and rgb frames.
Setting the registration mode, if supported, will align depth and rgb :)

iOS waveform generator connected via AUGraph

I have created a simple waveform generator which is connected to an AUGraph. I have reused some sample code from Apple to set AudioStreamBasicDescription like this
void SetCanonical(UInt32 nChannels, bool interleaved)
// note: leaves sample rate untouched
{
mFormatID = kAudioFormatLinearPCM;
int sampleSize = SizeOf32(AudioSampleType);
mFormatFlags = kAudioFormatFlagsCanonical;
mBitsPerChannel = 8 * sampleSize;
mChannelsPerFrame = nChannels;
mFramesPerPacket = 1;
if (interleaved)
mBytesPerPacket = mBytesPerFrame = nChannels * sampleSize;
else {
mBytesPerPacket = mBytesPerFrame = sampleSize;
mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
}
}
In my class I call this function
mClientFormat.SetCanonical(2, true);
mClientFormat.mSampleRate = kSampleRate;
while sample rate is
#define kSampleRate 44100.0f;
The other setting are taken from sample code as well
// output unit
CAComponentDescription output_desc(kAudioUnitType_Output, kAudioUnitSubType_RemoteIO, kAudioUnitManufacturer_Apple);
// iPodEQ unit
CAComponentDescription eq_desc(kAudioUnitType_Effect, kAudioUnitSubType_AUiPodEQ, kAudioUnitManufacturer_Apple);
// multichannel mixer unit
CAComponentDescription mixer_desc(kAudioUnitType_Mixer, kAudioUnitSubType_MultiChannelMixer, kAudioUnitManufacturer_Apple);
Everything works fine, but the problem is that I am not getting stereo sound and my callback function is failing (bad access) when I try to reach the second buffer
Float32 *bufferLeft = (Float32 *)ioData->mBuffers[0].mData;
Float32 *bufferRight = (Float32 *)ioData->mBuffers[1].mData;
// Generate the samples
for (UInt32 frame = 0; frame < inNumberFrames; frame++)
{
switch (generator.soundType) {
case 0: //Sine
bufferLeft[frame] = sinf(thetaLeft) * amplitude;
bufferRight[frame] = sinf(thetaRight) * amplitude;
break;
So it seems I am getting mono instead of stereo. The pointer bufferRight is empty, but don't know why.
Any help will be appreciated.
I can see two possible errors. First, as #invalidname pointed out, recording in stereo probably isn't going to work on a mono device such as the iPhone. Well, it might work, but if it does, you're just going to get back dual-mono stereo streams anyways, so why bother? You might as well configure your stream to work in mono and spare yourself the CPU overhead.
The second problem is probably the source of your sound distortion. Your stream description format flags should be:
kAudioFormatFlagIsSignedInteger |
kAudioFormatFlagsNativeEndian |
kAudioFormatFlagIsPacked
Also, don't forget to set the mReserved flag to 0. While the value of this flag is probably being ignored, it doesn't hurt to explicitly set it to 0 just to make sure.
Edit: Another more general tip for debugging audio on the iPhone -- if you are getting distortion, clipping, or other weird effects, grab the data payload from your phone and look at the recording in a wave editor. Being able to zoom down and look at the individual samples will give you a lot of clues about what's going wrong.
To do this, you need to open up the "Organizer" window, click on your phone, and then expand the little arrow next to your application (in the same place where you would normally uninstall it). Now you will see a little downward pointing arrow, and if you click it, Xcode will copy the data payload from your app to somewhere on your hard drive. If you are dumping your recordings to disk, you'll find the files extracted here.
reference from link
I'm guessing the problem is that you're specifying an interleaved format, but then accessing the buffers as if they were non-interleaved in your IO callback. ioData->mBuffers[1] is invalid because all the data, both left and right channels, is interleaved in ioData->mBuffers[0].mData. Check ioData->mNumberBuffers. My guess is it is set to 1. Also, verify that ioData->mBuffers[0].mNumberChannels is set to 2, which would indicate interleaved data.
Also check out the Core Audio Public Utility classes to help with things like setting up formats. Makes it so much easier. Your code for setting up format could be reduced to one line, and you'd be more confident it is right (though to me your format looks set up correctly - if what you want is interleaved 16-bit int):
CAStreamBasicDescription myFormat(44100.0, 2, CAStreamBasicDescription::kPCMFormatInt16, true)
Apple used to package these classes up in the SDK that was installed with Xcode, but now you need to download them here: https://developer.apple.com/library/mac/samplecode/CoreAudioUtilityClasses/Introduction/Intro.html
Anyway, it looks like the easiest fix for you is to just change the format to non-interleaved. So in your code: mClientFormat.SetCanonical(2, false);

How to extract a function from highgui module(opencv)and place in the code file

this might be a silly question, but I need to know if for the code below, if i can extract the cvCaptureFromCAM() function from the highgui.lib and paste it in my code so that I can rename it to camcapture() and then call that within my program without just including the highgui library file at the beginning of the code file:
CvCapture * pCapture = 0;
//Initialize video capture
pCapture = cvCaptureFromCAM( CV_CAP_ANY );
Many Thanks
It is possible! However, after a couple of days you will eventually realize OpenCV relies on other libraries to do its job, meaning you would also need to dig into those libraries in order to get everything to make cvCaptureFromCAM() work on your application without linking it with OpenCV.
Now, think about this for a second, even if you succeeded, how would you retrieve/save/display images from the camera without using other OpenCV functions like cvShowImage(), cvGrabFrame(), etc. Consider all the hard work you would also have for stripping this functions from the library. Is it worth it?
In case you're just trying to make your code cleaner, you could make a simple wrapper around cvCaptureFromCAM(), and simply call camcapture() from inside your main() function.
/* Global variables */
CvCapture* capture = NULL;
void camcapture()
{
capture = cvCaptureFromCAM(CV_CAP_ANY);
}
Another thing you could do is use the videoInput library. It uses DirectX to get access to the webcam.
More info here: http://aishack.in/tutorials/capturing-images-with-directx/