Specifying the type of the vehicule detected in a Video frame - matlab

I am trying to detect vehicules in a video frame. More specifically to detect vehicules and then count the number of the detected vehicules.
By the way, I am using the MATLAB code of MathWorks: Open this link
So you can find more details in the above link...
Assume that we extract a specific frame of a video. What I need, is to extend the code by adding more lines which have the ability to further specify the type of the detected vehicule (if it is a car or track? for example).
Concerning the original code used by Mathworks:
1) Import the video (to be processed) and initialize a Foreground Color Detector:
The motivation is to make the processing of the video more easy. So instead of processing the entire video, we can thus apply our processing in a frame in which all the moving objects are segmented from the background. The foreground detector requires a certain number of video frames in order to initialize the Gaussian mixture model. This example uses the first 50 frames to initialize three Gaussian modes in the mixture model.
foregroundDetector = vision.ForegroundDetector('NumGaussians', 3, ...
'NumTrainingFrames', 50);
videoReader = vision.VideoFileReader('visiontraffic.avi');
for i = 1:150
frame = step(videoReader); % read the next video frame
foreground = step(foregroundDetector, frame);
end
2) Detecting vehicule in the video frame:
Unfortunately, the Foreground color detector is not perfect since it provides some adding noises. So It will be interesting to implement the "morphological idea" in order to remove the added noise:
se = strel('square', 3);
filteredForeground = imopen(foreground, se);
figure; imshow(filteredForeground); title('Clean Foreground');
3) Next, we find bounding boxes of each connected component corresponding to a moving car by using vision.BlobAnalysis object. The object further filters the detected foreground by rejecting blobs which contain fewer than 150 pixels.
blobAnalysis = vision.BlobAnalysis('BoundingBoxOutputPort', true, ...
'AreaOutputPort', false, 'CentroidOutputPort', false, ...
'MinimumBlobArea', 150);
bbox = step(blobAnalysis, filteredForeground);
4) Lets highlight each detected vehicule by a small rectangular box:
result = insertShape(frame, 'Rectangle', bbox, 'Color', 'green');
5) Counting the number of vehicules that appear in the video frame:
numCars = size(bbox, 1);
result = insertText(result, [10 10], numCars, 'BoxOpacity', 1, ...
'FontSize', 14);
Kindly I will appreciate very much your help.

This problem is an active research area, and there are many possible approaches. One possibility is to train a classifier to distinguish a car from a truck. You can use this example showing how to classify digits using HOG features and an SVM classifier to get started.

Related

Getting the coordinates of vertices of an A4 sheet with coins on it, for its further projective transformation and coin detection

I need to transform my tilted image in a way I can find coins on an A4 paper. So far, I have been getting four coordinates of edges of my paper by manually selecting them with ginput.
targetImageData = imread('coin1.jpg');
imshow(targetImageData);
fprintf('Corner selection must be clockwise or anti-clockwise.\n');
[X,Y] = ginput(4);
Is there a way to automate this process, say, apply some edge detector and then find coordinates of each vertex and then pass them as the coordinates needed for transformation?
Manual selection:
Result:
You can try using detectHarrisFeatures on the S color channel of HSV color space:
I was looking for a color space that gets maximum contrast of the paper.
It looks like the saturation color channel of HSV makes a good contrast between the paper and the background.
Image is resized the image by a factor of 0.25, for removing noise.
detectHarrisFeatures finds the 4 corners of the paper, but it might not be robust enough.
You may need to find more features, and find the 4 correct features, using some logic.
Here is a code sample:
%Read input image
I = imread('im.png');
%Remove the margins, and replace them using padding (just because the image is a MATLAB figure)
I = padarray(I(11:end-10, 18:end-17, :), [10, 17], 'both', 'replicate');
HSV = rgb2hsv(I);
%H = HSV(:, :, 1);%figure;imshow(H);title('H');
S = HSV(:, :, 2);%figure;imshow(S);title('S');
%V = HSV(:, :, 3);%figure;imshow(V);title('V');
%Reduce image size by a factor of 0.25 in each axis
S = imresize(S, 0.25);
%S = imclose(S, ones(3)); %May be requiered
%Detect corners
corners = detectHarrisFeatures(S);
imshow(S); hold on;
plot(corners.selectStrongest(4));
Result:
Different approach you may try:
Take a photo without the coins.
Mark the corners manually, and extract features of the 4 corners.
Use image matching techniques to match the image with the coins with the image without the coins (mach basted on the 4 corners).

Align already captured rgb and depth images

I am trying to allign two images - one rgb and another depth using MATLAB. Please note that I have checked several places for this - like here , here which requires a kinect device, and here here which says that camera parameters are required for calibration. I was also suggested to use EPIPOLAR GEOMETRY to match the two images though I do not know how. The dataset I am referring to is given in rgb-d-t face dataset. One such example is illustrated below :
The ground truth which basically means the bounding boxes which specify the face region of interest are already provided and I use them to crop the face regions only. The matlab code is illustrated below :
I = imread('1.jpg');
I1 = imcrop(I,[218,198,158,122]);
I2 = imcrop(I,[243,209,140,108]);
figure, subplot(1,2,1),imshow(I1);
subplot(1,2,2),imshow(I2);
The two cropped images rgb and depth are shown below :
Is there any way by which we can register/allign the images. I took the hint from
here where basic sobel operator has been used on both the rgb and depth images to generate an edge map and then keypoints will need to be generated for matching purposes. The edge maps for both the images are generated here.
.
However they are so noisy that I do not think we will be able to do keypoint matching for this images.
Can anybody suggest some algorithms in matlab to do the same ?
prologue
This answer is based on mine previous answer:
Does Kinect Infrared View Have an offset with the Kinect Depth View
I manually crop your input image so I separate colors and depth images (as my program need them separated. This could cause minor offset change by few pixels. Also as I do not have the depths (depth image is 8bit only due to grayscale RGB) then the depth accuracy I work with is very poor see:
So my results are affected by all this negatively. Anyway here is what you need to do:
determine FOV for both images
So find some measurable feature visible on both images. The bigger in size the more accurate the result. For example I choose these:
form a point cloud or mesh
I use depth image as reference so my point cloud is in its FOV. As I do not have the distances but 8bit values instead I converted that to some distance by multiplying by constant. So I scan whole depth image and for every pixel I create point in my point cloud array. Then convert the dept pixel coordinate to color image FOV and copy its color too. something like this (in C++):
picture rgb,zed; // your input images
struct pnt3d { float pos[3]; DWORD rgb; pnt3d(){}; pnt3d(pnt3d& a){ *this=a; }; ~pnt3d(){}; pnt3d* operator = (const pnt3d *a) { *this=*a; return this; }; /*pnt3d* operator = (const pnt3d &a) { ...copy... return this; };*/ };
pnt3d **xyz=NULL; int xs,ys,ofsx=0,ofsy=0;
void copy_images()
{
int x,y,x0,y0;
float xx,yy;
pnt3d *p;
for (y=0;y<ys;y++)
for (x=0;x<xs;x++)
{
p=&xyz[y][x];
// copy point from depth image
p->pos[0]=2.000*((float(x)/float(xs))-0.5);
p->pos[1]=2.000*((float(y)/float(ys))-0.5)*(float(ys)/float(xs));
p->pos[2]=10.0*float(DWORD(zed.p[y][x].db[0]))/255.0;
// convert dept image x,y to color image space (FOV correction)
xx=float(x)-(0.5*float(xs));
yy=float(y)-(0.5*float(ys));
xx*=98.0/108.0;
yy*=106.0/119.0;
xx+=0.5*float(rgb.xs);
yy+=0.5*float(rgb.ys);
x0=xx; x0+=ofsx;
y0=yy; y0+=ofsy;
// copy color from rgb image if in range
p->rgb=0x00000000; // black
if ((x0>=0)&&(x0<rgb.xs))
if ((y0>=0)&&(y0<rgb.ys))
p->rgb=rgb2bgr(rgb.p[y0][x0].dd); // OpenGL has reverse RGBorder then my image
}
}
where **xyz is my point cloud 2D array allocated t depth image resolution. The picture is my image class for DIP so here some relevant members:
xs,ys is the image resolution in pixels
p[ys][xs] is the image direct pixel access as union of DWORD dd; BYTE db[4]; so I can access color as single 32 bit variable or each color channel separately.
rgb2bgr(DWORD col) just reorder color channels from RGB to BGR.
render it
I use OpenGL for this so here the code:
glBegin(GL_QUADS);
for (int y0=0,y1=1;y1<ys;y0++,y1++)
for (int x0=0,x1=1;x1<xs;x0++,x1++)
{
float z,z0,z1;
z=xyz[y0][x0].pos[2]; z0=z; z1=z0;
z=xyz[y0][x1].pos[2]; if (z0>z) z0=z; if (z1<z) z1=z;
z=xyz[y1][x0].pos[2]; if (z0>z) z0=z; if (z1<z) z1=z;
z=xyz[y1][x1].pos[2]; if (z0>z) z0=z; if (z1<z) z1=z;
if (z0 <=0.01) continue;
if (z1 >=3.90) continue; // 3.972 pre vsetko nad .=3.95m a 4.000 ak nechyti vobec nic
if (z1-z0>=0.10) continue;
glColor4ubv((BYTE* )&xyz[y0][x0].rgb);
glVertex3fv((float*)&xyz[y0][x0].pos);
glColor4ubv((BYTE* )&xyz[y0][x1].rgb);
glVertex3fv((float*)&xyz[y0][x1].pos);
glColor4ubv((BYTE* )&xyz[y1][x1].rgb);
glVertex3fv((float*)&xyz[y1][x1].pos);
glColor4ubv((BYTE* )&xyz[y1][x0].rgb);
glVertex3fv((float*)&xyz[y1][x0].pos);
}
glEnd();
You need to add the OpenGL initialization and camera settings etc of coarse. Here the unaligned result:
align it
If you notice I added ofsx,ofsy variables to copy_images(). This is the offset between cameras. I change them on arrows keystrokes by 1 pixel and then call copy_images and render the result. This way I manually found the offset very quickly:
As you can see the offset is +17 pixels in x axis and +4 pixels in y axis. Here side view to better see the depths:
Hope It helps a bit
Well I have tried doing it after reading lots of blogs and all. I am still not sure whether I am doing it correct or not. Please feel free to give comments if something is found amiss. For this I used a mathworks fex submission that can be found here : ginputc function.
The matlab code is as follows :
clc; clear all; close all;
% no of keypoint
N = 7;
I = imread('2.jpg');
I = rgb2gray(I);
[Gx, Gy] = imgradientxy(I, 'Sobel');
[Gmag, ~] = imgradient(Gx, Gy);
figure, imshow(Gmag, [ ]), title('Gradient magnitude')
I = Gmag;
[x,y] = ginputc(N, 'Color' , 'r');
matchedpoint1 = [x y];
J = imread('2.png');
[Gx, Gy] = imgradientxy(J, 'Sobel');
[Gmag, ~] = imgradient(Gx, Gy);
figure, imshow(Gmag, [ ]), title('Gradient magnitude')
J = Gmag;
[x, y] = ginputc(N, 'Color' , 'r');
matchedpoint2 = [x y];
[tform,inlierPtsDistorted,inlierPtsOriginal] = estimateGeometricTransform(matchedpoint2,matchedpoint1,'similarity');
figure; showMatchedFeatures(J,I,inlierPtsOriginal,inlierPtsDistorted);
title('Matched inlier points');
I = imread('2.jpg'); J = imread('2.png');
I = rgb2gray(I);
outputView = imref2d(size(I));
Ir = imwarp(J,tform,'OutputView',outputView);
figure; imshow(Ir, []);
title('Recovered image');
figure,imshowpair(I,J,'diff'),title('Difference with original');
figure,imshowpair(I,Ir,'diff'),title('Difference with restored');
Step 1
I used the sobel edge detector to extract the edges for both the depth and rgb images and then used a thresholding values to get the edge map. I will be primarily working with the gradient magnitude only. This gives me two images as this :
Step 2
Next I use the ginput or ginputc function to mark keypoints on both the images. The correspondence between the points are established by me beforehand. I tried using SURF features but they do not work well on depth images.
Step 3
Use the estimategeometrictransform to get the transformation matrix tform and then use this matrix to recover the original position of the moved image. The next set of images tells this story.
Granted I still believe the results can be further improved if the keypoint selections in either of the images are more judiciously done. I also think #Specktre method is better. I just noticed that I used a separate image-pair in my answer compared to that of the question. Both images come from the same dataset to be found here vap rgb-d-t dataset.

Warp images using motion maps generated by opticalFlowLKDoG (Matlab 2015A)

This question is based on a modified Matlab code from the online documentation for the optical flow system objects in version 2015a as appears in opticalFlowLK class
clc; clearvars; close all;
inputVid = VideoReader('viptraffic.avi');
opticFlow = opticalFlowLKDoG('NumFrames',3);
inputVid.currentTime = 2;
k = 1;
while inputVid.currentTime<=2 + 1/inputVid.FrameRate
frameRGB{k} = readFrame(inputVid);
frameGray{k} = rgb2gray(frameRGB{k});
flow{k} = estimateFlow(opticFlow,frameGray{k});
k = k+1;
end
By looking at flow{2}.Vx and flow{2}.Vy I get the motion maps U and V that describe the motion from frameGray{1} to frameGray{2}.
Iwant to use flow{2}.Vx and flow{2}.Vy directly on the data in frameGray{1} in order to warp frameGray{1} to appear visually similar to frameGray{2}.
I tried this code:
[x, y] = meshgrid(1:size(frameGray{1},2), 1:size(frameGray{1},1));
frameGray1Warped = interp2(double(frameGray{1}) , x-flow{2}.Vx , y-flow{2}.Vy);
But it doesn't seem to do much at all except ruin the image quality (but the objects don't display any real motion towards their locations in frameGray{2}.
I added 3 images showing the 2 original frames followed by frame 1 warped using the motion field to appear similar to frame 2:
It can be seen easily that frame 1 warped to 2 is essentially frame 1 with degraded quality but the cars haven't moved at all. That is - the location of the cars is the same: look at the car closest to the camera with respect to the road separation line near it; it's virtually the same in frame 1 and frame 1 warped to 2, but is quite different in frame 2.

How to track a face that is 5m away from source in facial detection for matlab?

I am currently trying to figure out how to be able to detect a face that is 5m away from the source and will have its facial features clear enough for the user to see. The code i am working on is as shown.
faceDetector = vision.CascadeObjectDetector();
%Get the input device using image acquisition toolbox,resolution = 640x480 to improve performance
obj =imaq.VideoDevice('winvideo', 1, 'YUY2_640x480','ROI', [1 1 640 480]);
set(obj,'ReturnedColorSpace', 'rgb');
figure('menubar','none','tag','webcam');
while (true)
frame=step(obj);
bbox=step(faceDetector,frame);
boxInserter = vision.ShapeInserter('BorderColor','Custom',...
'CustomBorderColor',[255 255 0]);
videoOut = step(boxInserter, frame,bbox);
imshow(videoOut,'border','tight');
f=findobj('tag','webcam');
if (isempty(f));
[hueChannel,~,~] = rgb2hsv(frame);
% Display the Hue Channel data and draw the bounding box around the face.
figure, imshow(hueChannel), title('Hue channel data');
rectangle('Position',bbox,'EdgeColor','r','LineWidth',1)
hold off
noseDetector = vision.CascadeObjectDetector('Nose');
faceImage = imcrop(frame,bbox);
imshow(faceImage)
noseBBox = step(noseDetector,faceImage);
noseBBox(1:1) = noseBBox(1:1) + bbox(1:1);
videoInfo = info(obj);
ROI=get(obj,'ROI');
VideoSize = [ROI(3) ROI(4)];
videoPlayer = vision.VideoPlayer('Position',[300 300 VideoSize+30]);
tracker = vision.HistogramBasedTracker;
initializeObject(tracker, hueChannel, bbox);
while (1)
% Extract the next video frame
frame = step(obj);
% RGB -> HSV
[hueChannel,~,~] = rgb2hsv(frame);
% Track using the Hue channel data
bbox = step(tracker, hueChannel);
% Insert a bounding box around the object being tracked
videoOut = step(boxInserter, frame, bbox);
%Insert text coordinates
% Display the annotated video frame using the video player object
step(videoPlayer, videoOut);
pause (.2)
end
% Release resources
release(obj);
release(videoPlayer);
close(gcf)
break
end
pause(0.05)
end
release(obj)
% remove video object from memory
delete(handles.vid);
I am trying to work on this code to figure out the distance it can cover when tracking a face. I couldnt figure out which one handles that. Thanks!
Not sure what your question is, but try this example. It uses the KLT algorithm, which, IMHO, is more robust for face tracking than CAMShift. It also uses the webcam interface in base MATLAB, which is very easy.

Recording/playback Kinect with Matlab - upside down and in black/white rather than gray scale

I am trying to write a program to record and playback both colour and depth streams from a xbox kinect to ease testing image processing programs. Currently I have the bulk done and the colour stream works fine. I am however having trouble with the depth stream.
Currently, the depth stream is playing back upside down and only in black and white. I have 3 thoughts as to why this may be the case:
1) The conversion to 8-bit from 11-bit
2) the Motion JPEG 2000 format (never used this before)
3) the colormap is wrong
Below is the code I am using. I feel I cannot be the only one trying to do this so any pointer and help would be much appreciated as I couldn't find anything this specific on the web.
%------------------------------------------------
%------------------------------------------------
%Code to record kinect colour and sensor data
%using code supplied on http://www.mathworks.co.uk/help/imaq/examples/using-the- kinect-r-for-windows-r-from-image-acquisition-toolbox-tm.html
%and http://www.mathworks.co.uk/help/imaq/examples/logging-data-to-disk.html
%------------------------------------------------
%------------------------------------------------
dbstop if error
imaqreset %deletes any image acquisition objects that exsist in memory and uploads all adaptors loaded by the toolbox. As a result, image acquisition hardware is reset
%------------------------------------------------
%setting up video streams
%------------------------------------------------
disp('Setting up video streams');
%Call up dicertory containing utility functions
utilpath = fullfile(matlabroot, 'toolbox', 'imaq', 'imaqdemos', 'html', 'KinectForWindows');
addpath(utilpath);
%Create the videoinput objects for the colour and depth streams
colourVid = videoinput('kinect', 1, 'RGB_640x480');
%preview(colourVid);
depthVid = videoinput('kinect', 2, 'Depth_640x480');
%set backlight compensation with centre priority
%set(colourVid, 'BacklightCompensation', 'CentrePriority');
%Set camera angle to 0
%set(colourVid, 'CameraElevationAngle', 0);
disp('Video stream set-up complete');
%------------------------------------------------
%setting up record
%------------------------------------------------
% set the data streams to logging mode and to disk
set(colourVid, 'LoggingMode', 'Disk&Memory');
set(depthVid, 'LoggingMode', 'Disk&Memory');
%Set a video timeout property limit to 50 seconds from
%www.mathworks.com/matlabcentral/answers/103543-why-do-i-receive-the-error-getdata-timed-out-before-frames-were-available-when-using-getdata-in-im
set(colourVid, 'Timeout',50);
set(depthVid, 'Timeout',50);
%Creat a VideoReader object
colourLogfile = VideoWriter('colourTrial5.mj2', 'Motion JPEG 2000');
depthLogfile = VideoWriter('depthTrial5.mj2', 'Motion JPEG 2000');
%configure the video input object to use the VideoWriter object
colourVid.DiskLogger = colourLogfile;
depthVid.DiskLogger = depthLogfile;
%set the triggering mode to 'manual'
triggerconfig([colourVid depthVid], 'manual');
%set the FramePerTrigger property of the VIDEOINPUT objects to 100 to
%acquire 100 frames per trigger.
set([colourVid depthVid], 'FramesPerTrigger', 200);
disp('Video record set-up complete');
%------------------------------------------------
%Initiating the aquisition
%------------------------------------------------
disp('Starting Steam');
%Start the colour and depth device. This begins acquisition, but does not
%start logging of acquired data
start([colourVid depthVid]);
pause(20); %allow time for both streams to start
%Trigger the devices to start logging of data.
trigger([colourVid depthVid]);
%Retrieve the acquired data
[colourFrameData, colourTimeData, colourMetaData] = getdata(colourVid);
[depthFrameData, depthTimeData, depthMetaData] = getdata(depthVid);
stop([colourVid depthVid])
disp('Recording Complete')
%------------------------------------------------
%Play back recordings
%------------------------------------------------
disp('Construct playback objects')
colourPlayback = VideoReader('colourTrial5.mj2');
depthPlayback = VideoReader('depthTrial5.mj2');
%Set colour(c) playback parameters
cFrames = colourPlayback.NumberOfFrames;
cHeight = colourPlayback.Height;
cWidth = colourPlayback.Width;
%Preallocate movie structure
colourMov(1:cFrames)=struct('cdata', zeros(cHeight,cWidth,3,'uint8'),'colormap',[]);
disp('Reading colour frames one by one')
%read one frame at a time
for k = 1:cFrames
colourMov(k).cdata=read(colourPlayback,k);
end
disp('Sizing figure for colour playback')
%Size a figure based on the video's width and height
hf1=figure;
set(hf1,'position',[150 150 cWidth cHeight])
disp('Playing Colour recording')
%play back the movie once at the video's frame rate
movie(hf1,colourMov,1,colourPlayback.FrameRate);
%Set depth(d) playback parameters
dFrames = depthPlayback.NumberOfFrames;
dHeight = depthPlayback.Height;
dWidth = depthPlayback.Width;
%Preallocate movie structure
depthMov(1:dFrames)=struct('cdata', zeros(dHeight,dWidth,3,'uint8'),'colormap',gray(256));
disp('Reading depth frames one by one')
%read one frame at a time
for k = 1:dFrames
depthMov(k).cdata=uint8(read(depthPlayback,k));
%depthMov(k)=imrotate(depthMov(k),180); %tried this to no effect
end
disp('Sizing figure for depth playback')
%Size a figure based on the video's width and height
hf2=figure;
set(hf2,'position',[150 150 dWidth dHeight])
disp('Playing Depth recording')
%play back the movie once at the video's frame rate
movie(hf2,depthMov,1,depthPlayback.FrameRate);
%clear videos from workspace
delete([colourVid depthVid])
clear [colourVid depthVid]
Your script is well-written and correct, except for how you display the depth data.
The Kinect records depth as 16-bit unsigned integers. The pixel value in the depth frame is the distance in millimeters of whatever object is in that pixel from the plane of the camera. So, if the depth value of a pixel of an object you care about reads out as, e.g., 1723, that means that part of the object is 1.723 meters away from the camera.
So, how does that relate to your broken display functionality? Here's your old display snippet:
%read one frame at a time
for k = 1:dFrames
depthMov(k).cdata=uint8(read(depthPlayback,k));
end
The problem is right there at uint8. Many of your depth values I'm sure are beyond 255, meaning objects in your scene are farther than 0.2 meters from the camera. In fact, the Kinect cannot even sense data that close! The nearest you can detect depth, with DepthMode set to Near, is about 0.4 meters.
So, here's how to solve the display issue:
%read one frame at a time
maxDistFromCamera = 1600; % 1600 millimeters
for k = 1:dFrames
% Depth frames are int16.
depthFrame = read(depthPlayback,k);
% We'll rescale the image from [0,maxDistFromCamera] to [0,255]
depthFrame = 255.0*single(depthFrame)/maxDistFromCamera;
% And then recast it to uint8 for display.
depthMov(k).cdata=uint8(depthFrame);
end
Below is reproduced the whole script, with my edits, for convenience.
%------------------------------------------------
%------------------------------------------------
%Code to record kinect colour and sensor data
%using code supplied on http://www.mathworks.co.uk/help/imaq/examples/using-the- kinect-r-for-windows-r-from-image-acquisition-toolbox-tm.html
%and http://www.mathworks.co.uk/help/imaq/examples/logging-data-to-disk.html
%------------------------------------------------
%------------------------------------------------
imaqreset %deletes any image acquisition objects that exsist in memory and uploads all adaptors loaded by the toolbox. As a result, image acquisition hardware is reset
%------------------------------------------------
%setting up video streams
%------------------------------------------------
disp('Setting up video streams');
%Call up dicertory containing utility functions
utilpath = fullfile(matlabroot, 'toolbox', 'imaq', 'imaqdemos', 'html', 'KinectForWindows');
addpath(utilpath);
%Create the videoinput objects for the colour and depth streams
colourVid = videoinput('kinect', 1, 'RGB_640x480');
%preview(colourVid);
depthVid = videoinput('kinect', 2, 'Depth_320x240');
% Set the depth mode to near.
srcDepth = getselectedsource(depthVid);
srcColor = getselectedsource(colourVid);
set(srcDepth, 'DepthMode' , 'Near');
set(srcDepth, 'CameraElevationAngle', 0);
%set backlight compensation with centre priority
set(srcColor, 'BacklightCompensation', 'CenterPriority');
disp('Video stream set-up complete');
%------------------------------------------------
%setting up record
%------------------------------------------------
% set the data streams to logging mode and to disk
set(colourVid, 'LoggingMode', 'Disk&Memory');
set(depthVid, 'LoggingMode', 'Disk&Memory');
%Set a video timeout property limit to 50 seconds from
%www.mathworks.com/matlabcentral/answers/103543-why-do-i-receive-the-error-getdata-timed-out-before-frames-were-available-when-using-getdata-in-im
set(colourVid, 'Timeout',50);
set(depthVid, 'Timeout',50);
%Creat a VideoReader object
colourLogfile = VideoWriter('colourTrial5.mj2', 'Motion JPEG 2000');
depthLogfile = VideoWriter('depthTrial5.mj2', 'Archival');
%configure the video input object to use the VideoWriter object
colourVid.DiskLogger = colourLogfile;
depthVid.DiskLogger = depthLogfile;
%set the triggering mode to 'manual'
triggerconfig([colourVid depthVid], 'manual');
%set the FramePerTrigger property of the VIDEOINPUT objects to 100 to
%acquire 100 frames per trigger.
set([colourVid depthVid], 'FramesPerTrigger', 30);
disp('Video record set-up complete');
%------------------------------------------------
%Initiating the aquisition
%------------------------------------------------
disp('Starting Steam');
%Start the colour and depth device. This begins acquisition, but does not
%start logging of acquired data
start([colourVid depthVid]);
pause(20); %allow time for both streams to start
disp('Starting Depth Stream');
%Trigger the devices to start logging of data.
trigger([colourVid depthVid]);
%Retrieve the acquired data
[colourFrameData, colourTimeData, colourMetaData] = getdata(colourVid);
[depthFrameData, depthTimeData, depthMetaData] = getdata(depthVid);
stop([colourVid depthVid])
disp('Recording Complete')
%------------------------------------------------
%Play back recordings
%------------------------------------------------
disp('Construct playback objects')
colourPlayback = VideoReader('colourTrial5.mj2');
depthPlayback = VideoReader('depthTrial5.mj2');
%Set colour(c) playback parameters
cFrames = colourPlayback.NumberOfFrames;
cHeight = colourPlayback.Height;
cWidth = colourPlayback.Width;
%Preallocate movie structure
colourMov(1:cFrames)=struct('cdata', zeros(cHeight,cWidth,3,'uint8'),'colormap',[]);
disp('Reading colour frames one by one')
%read one frame at a time
for k = 1:cFrames
colourMov(k).cdata=read(colourPlayback,k);
end
disp('Sizing figure for colour playback')
%Size a figure based on the video's width and height
hf1=figure;
set(hf1,'position',[150 150 cWidth cHeight])
disp('Playing Colour recording')
%play back the movie once at the video's frame rate
movie(hf1,colourMov,1,colourPlayback.FrameRate);
%Set depth(d) playback parameters
dFrames = depthPlayback.NumberOfFrames;
dHeight = depthPlayback.Height;
dWidth = depthPlayback.Width;
%Preallocate movie structure
depthMov(1:dFrames)=struct('cdata', zeros(dHeight,dWidth,3,'uint8'),'colormap',gray(256));
disp('Reading depth frames one by one')
%read one frame at a time
maxDistFromCamera = 1600; % 1600 millimeters
for k = 1:dFrames
% Depth frames are int16.
depthFrame = read(depthPlayback,k);
% We'll rescale the image from [0,maxDistFromCamera] to [0,255]
depthFrame = 255.0*single(depthFrame)/maxDistFromCamera;
% And then recast it to uint8 for display.
depthMov(k).cdata=uint8(depthFrame);
end
disp('Sizing figure for depth playback')
%Size a figure based on the video's width and height
hf2=figure;
set(hf2,'position',[150 150 dWidth dHeight])
disp('Playing Depth recording')
%play back the movie once at the video's frame rate
movie(hf2,depthMov,1,depthPlayback.FrameRate);
%clear videos from workspace
delete([colourVid depthVid])
clear [colourVid depthVid]
close all;
There are some minor textual differences, for instance, my Kinect SDK requires different spelling of some parameters, which I just fixed inline. I also disabled the aggressive debugging setting you had on at the top. Not important, just making a note of it. Lastly, I set the VideoWriter format to Archival for the depth stream, so that none of the depth values are corrupted on save (important for precise depth measurement applications, which is what I tend to be up to these days).