I have made some research here to understand this topic but I have not achieved good results. I'm working with a Kinect for Windows and the Kinect SDK 1.7. I'm working with matlab to process raw depth map info.
First, I'm using this method (https://stackoverflow.com/a/11732251/3416588) to store Kinect raw depth data to a text file. I got a list with (480x640 = 307200) elements and data like this:
23048
23048
23048
-8
-8
-8
-8
-8
-8
-8
-8
6704
6720
6720
6720
6720
6720
6720
6720
6720
6736
6736
6736
6736
6752
0
0
Then in Matlab I convert this values to binary. So, I get 16-bits numbers. The last three numbers that correspond to player index are "000", so I remove them. Now, from the 13 bits numbers, I remove the more significative, which is always "0".
So, I have made this:
[0,1,1,0,0,0,1,0,0,0,1,1,1,0,0,0] - 16 bits number
[0,1,1,0,0,0,1,0,0,0,1,1,1] - 13 bits number
[1,1,0,0,0,1,0,0,0,1,1,1] - 12 bits number
Then I follow to this procedure (https://stackoverflow.com/a/9678900/3416588) to convert raw-depth info to meters but i get values in the range from -4.7422 to 0.3055. What do they mean?
clc
clear all
close all
%Get raw depth data from .txt
fileID = fopen('C:\Example.txt', 'r');
datos = fscanf(fileID, '%i'); % Data in decimal
fclose(fileID);
% If raw depth data is less than 0, set it to 0
for i = 1 : 640*480
if(datos(i) < 0)
datos(i) = 0;
end
end
% Auxiliar arrays
datosBin = zeros(640*480, 16);
realDepth = zeros(640*480, 12);
% Decimal raw depth data to binary
n = 16;
m = 0;
for i = 1 : 640*480
a = datos(i);
datosBin(i,:) = fix(rem(a*pow2(-(n-1):m),2));
end
% Remove player index and msb (more significant bit)
for i = 1 : 640*480
realDepth(i,:) = datosBin(i,2:13);
end
% Auxiliar array to store raw depth data decimal number
realDepthDec = zeros(640*480,1);
% Raw depth data 12 bits to decimal
for i = 1 : 640*480
realDepthDec(i) = bin2dec(num2str(realDepth(i,:)));
end
% Auxiliar array
rawDepthMapMeters = zeros(480, 640);
% Create array 640*480 to store bit depth info in meters
for j = 1 : 480
for i = 1 : 640
if(realDepthDec(i+j) <= 2046)
rawDepthMapMeters(j, i) = 0.1236 * tan(realDepthDec(i+j)/2842.5 + 1.1863);
end
end
end
Where is my mistake? What am I doing wrong? Thanks in advance.
PS. Sorry for my bad english.
In the second article you read, you will see that the method you use is outdated. Read this.
x = (i - w / 2) * (z + minDistance) * scaleFactor
y = (j - h / 2) * (z + minDistance) * scaleFactor
z = z
Where
minDistance = -10
scaleFactor = .0021.
These values were found by hand.
Also you could convert those points to millimeters in your first application as described in the second question
using (var depthFrame = e.OpenDepthImageFrame())
{
var depthArray = new short[depthFrame.PixelDataLength];
depthFrame.CopyPixelDataTo(depthArray);
for (int i = 0; i < depthArray.Length; i++) {
int depthInMillimeters =
depthArray[i] >> DepthImageFrame.PlayerIndexBitmaskWidth;
// TADAx2!
}
Related
Demo data
Data set can be found here :
Dataset
Each point (x;y) indicated the value (y) of the xth sample measured
I am trying to bound a data region which has the most data points just like in the figure , by using 2 line y=a and y=b
How can i approach this solution
Let's say your minimum and maximum for y values are respectively 960 and 972:
y(y < 960) = 960;
y(y > 972) = 972;
Alternatively, you can remove those outliers instead of bounding them:
y_idx = find((y < 960) | (y > 972));
x(y_idx) = [];
y(y_idx) = [];
(Example) Point cloud data
Consider a matrix N x 36, where N is the number of points in the point cloud data (3D object) and 36 columns represent the features extracted of which the last 3 columns are (x, y, z) coordinate values of every point.
Now I wish to perform feature analysis in this regard I would like to know how to plot/represent/describe each feature from f1,f2,...f33 over the (x,y,z) coordinates for which they were computed? (to understand the behavior of features)
Is this possible? How? If not, what is the alternative?
Eg: find 2 features file bunny_example with NX5 where N is number of points, 1st and 2nd columns are features 1f1, f21 and 3rd to 5th columns are (x,y,z) coordinate values.
This code may help you:
% Provided example data
features = [2.0684e-05 7.5750e-06 3.8389e-05 1.0346e-05 -8.3302e-06;
0.0002 -1.7019e-05 -0.0002 -3.8879e-05 8.1841e-05;
-2.3888e-05 -3.5798e-05 2.0476e-05 -4.7382e-05 3.8213e-05;
7.7594e-06 2.9854e-06 3.0756e-05 -1.9135e-06 1.3463e-05;
3.4250e-05 5.6627e-06 7.3759e-06 -8.1303e-05 -1.5577e-05;
4.7731e-06 4.9014e-06 2.5750e-05 2.3827e-06 6.2936e-06;
2.4317e-05 0.0007 3.1783e-05 0.0001 -0.0001;
2.6632e-05 0.0009 0.0001 0.0001 -0.0005;
-1.9714e-05 -1.2456e-06 5.5657e-06 1.8092e-05 1.3787e-05];
points = [-0.6011 -0.9712 0.3268;
-0.5721 -0.9712 0.3379;
-0.5721 -0.9854 0.32794;
-0.5817 -0.948 0.3298;
0.0708 -0.583 -0.2528;
-0.5721 -0.9429 0.32794;
-0.312 -0.9940 0.4074;
-0.286 -0.994 0.4174;
-0.0864 0.4534 -0.7729];
% To create the colormap - like heatmap
initial_hsv = [0 1 1]; % red
final_hsv = [2/3 1 1]; % blue
point_size = 10;
max_hsv = max([initial_hsv; final_hsv]);
min_hsv = min([initial_hsv; final_hsv]);
dif_hsv = max_hsv - min_hsv;
% For each feature
for f = 1 : size(features, 2)
f_max = max(features(:, f));
f_min = min(features(:, f));
c_data = zeros(size(points, 1), 3);
% For each point
for p = 1 : size(points, 1)
for hsv_comp = 1:3
if dif_hsv(hsv_comp) != 0
% Logaritmic mapping
c_data(p, hsv_comp) = (1 - ((log(features(p, f)+abs(f_min)+1) - log(f_min+abs(f_min)+1)) / (log(f_max+abs(f_min)+1) - log(f_min+abs(f_min)+1)))) * dif_hsv(hsv_comp) + min_hsv(hsv_comp);
else
c_data(p, hsv_comp) = min_hsv(hsv_comp);
end
end
end
% Converting to HSV
c_data(:,:) = hsv2rgb(c_data(:,:));
% Creating a figure for each feature
str = sprintf('Feature number %d' , f);
figure
scatter3(points(:,1), points(:,2), points(:,3), point_size*ones(size(points,1),1), c_data);
title(str)
end
NOTES:
You can change the values of inital_hsv, final_hsv and point_size according to your needs.
The way the c_data is computed (in this example is used a logaritmic mapping) can also be changed in order to have smother color transitions based on your feature data.
i actually want to generate crc in matlab for Modbus protocol and i have used following code in matlab. I have also given message array as message=uint16([hex2dec('01') hex2dec('02') hex2dec('00') hex2dec('C4') hex2dec('00') hex2dec('16')]); and done bitand with 0xffff at the end, but it is unable to give correct crc..
My code is as below and the expected crc is B839 as per the Modbus crc calculator but it is giving B8DD(47325 decimal). Please help me if there is anything to change in the code. Thank you.
function crc_val = crc3 (~)
crc = uint16(hex2dec('1D0F')); % Non-augmented initial value equivalent to augmented initial value 0xFFFF
polynomial = hex2dec('1021'); % Polynomial
message=uint16([hex2dec('01') hex2dec('02') hex2dec('00') hex2dec('C4') hex2dec('00') hex2dec('16') hex2dec('00') hex2dec('00')]);
for i = 1:(length(message)-2) % Not taking the last 2 bytes because they are the CRC.
crc = bitxor(crc, bitsll(message(i), 8));
for j = 1:8
if (bitand(crc, hex2dec('8000')) > 0);
crc = bitxor(bitsll(crc, 1), polynomial);
else
crc = bitsll(crc, 1);
end
end
end
crc_val = bitand(crc, hex2dec('ffff'));
end
Did you try this. It is available as BSD license. You would not face any possible licensing issues. The following explains how CRC actually works. The following also helps understand the concept.
%usage: crc16(input vector).
//
function [resto] = crc16(h)
% g(X) = X^16+X^15+X^2+1
gx = [1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1];
% P(X) is given input vector
px = h;
%Calculate P(x)x^r
pxr=[px zeros(1,length(gx)-1)];
% deconvolve (r), entre pxr y gx
[c r]=deconv(pxr,gx);
r=mod(abs(r),2);
% returncrc-16
resto=r(length(px)+1:end);
end
The code is for MATLAB and i want to understand what exactly they are trying to do. I m new to matlab so need some advice. Please Help
function [key] = keyGen(n)
n = n*8;
% n = 2048*2048*16;
% n = 24 * 24 * 8;
bin_x = zeros(n,1,'uint8');
r = 3.9999998;
bin_x_N_Minus_1 = 0.300001;
x_N = 0;
tic
for ind = 2 : n
x_N = 1 - 2* bin_x_N_Minus_1 * bin_x_N_Minus_1;
if (x_N > 0.0)
bin_x(ind-1) = 1;
end
bin_x_N_Minus_1 = x_N;
end
toc
%save bin_sec bin_x;
t = uint8(0);
key = zeros(n/8,1,'uint8');
for ind1 = 1 : n/8
for ind2 = 1 : 8
key(ind1) = key(ind1) + bin_x(ind2*ind1)* 2 ^ (ind2-1);
end
end
The parameter n is the number of bytes in the key. n*8 is to convert that into a number of bits. bin_x is used to store the binary representation of the key. bin_x_N_Minus_1 is the value which we use to calculate the next bit.
In the first for loop, we loop through the bits in the key (the first bit is always a 0). We calculate x_N using that formula (bin_x_N_Minus_1 is the previous value of x_N). If x_N is positive, the corresponding bit in the key is 1, otherwise it is a zero.
tic and toc are used to time how long this for loop takes.
The second for loop converts the bits of the key into bytes, and stores them in output array, key. The Kth entry in key is the 8 bit number represented by taking every (N/8)th entry in bin_x, starting from K.
The variables r and t are unused.
I'm taking images using a tunneling microscope. However, the scope is drifting between successive images. I'm trying to use MatLab to calculate the offset between images. The code below calculates in seconds for small images (e.g. 64x64 pixels), but takes >2 hrs to handle the 512x512 pixel images I'm dealing with. Do you have any suggestions for speeding up this code? Or do you know of better ways to track images in MatLab? Thanks for your help!
%Test templates
template = .5*ones(32);
template(25:32,:) = 0;
template(:,25:64) = 0;
data_A = template;
close all
imshow(data_A);
template(9:32,41:64) = .5;
template(:,1:24) = 0;
data_B = template;
figure, imshow(data_B);
tic
[m n] = size(data_B);
z = [];
% Loop over all possible displacements
for x = -n:n
for y = -m:m
paddata_B = data_B;
ax = abs(x);
zerocols = zeros(m,ax);
if x > 0
paddata_B(:,1:ax) = [];
paddata_B = [paddata_B zerocols];
else
paddata_B(:,(n-ax+1):n) = [];
paddata_B = [zerocols paddata_B];
end
ay = abs(y);
zerorows = zeros(ay,n);
if y < 0
paddata_B(1:ay,:) = [];
paddata_B = vertcat(paddata_B, zerorows);
else
paddata_B((m-ay+1):m,:) = [];
paddata_B = vertcat(zerorows, paddata_B);
end
% Full matrix sum after array multiplication
C = paddata_B.*data_A;
matsum = sum(sum(C));
% Populate array of matrix sums for each displacement
z(x+n+1, y+m+1) = matsum;
end
end
toc
% Plot matrix sums
figure, surf(z), shading flat
% Find maximum value of z matrix
[max_z, imax] = max(abs(z(:)));
[xpeak, ypeak] = ind2sub(size(z),imax(1))
% Calculate displacement in pixels
corr_offset = [(xpeak-n-1) (ypeak-m-1)];
xoffset = corr_offset(1)
yoffset = corr_offset(2)
What you're calculating is known as the cross-correlation of the two images. You can calculate the cross-correlation of all offsets at once using Discrete Fourier Transforms (DFT or FFT). So try something like
z = ifft2( fft2(dataA) .* fft2(dataB).' );
If you pad with zeros in the Fourier domain, you can even use this sort of math to get offsets in fractions of a pixel, and apply offsets of fractions of a pixel to an image.
A typical approach to this kind of problem is to use the fact that it works quickly for small images to your advantage. When you have large images, decimate them to make small images. Register the small images quickly and use the computed offset as your initial value for the next iteration. In the next iteration, you don't decimate the images as much, but you're starting with a good initial estimate of the offset so you can constrain your search for solutions to a small neighborhood near your initial estimate.
Although not written with tunneling microscopes in mind, a review paper that may be of some assistance is: "Mutual Information-Based Registration of Medical Images: A Survey" by Pluim, Maintz, and Viergever published in IEEE Transactions on Medical Imaging, Vol. 22, No. 8, p. 986.
below link will help you find transformation between 2 images and correct/recover the distorted (in your case, image with offset)
http://in.mathworks.com/help/vision/ref/estimategeometrictransform.html
index_pairs = matchFeatures(featuresOriginal,featuresDistorted, 'unique', true);
matchedPtsOriginal = validPtsOriginal(index_pairs(:,1));
matchedPtsDistorted = validPtsDistorted(index_pairs(:,2));
[tform,inlierPtsDistorted,inlierPtsOriginal] = estimateGeometricTransform(matchedPtsDistorted,matchedPtsOriginal,'similarity');
figure; showMatchedFeatures(original,distorted,inlierPtsOriginal,inlierPtsDistorted);
The inlierPtsDistored, inlierPtsOriginal have attributes called locations.
These are nothing but matching locations of one image on another. I think from that point it is very easy to calculate offset.
The function below was my attempt to compute the cross-correlation of the two images manually. Something's not quite right though. Will look at it again this weekend if I have time. You can call the function with something like:
>> oldImage = rand(64);
>> newImage = circshift(oldImage, floor(64/2)*[1 1]);
>> offset = detectOffset(oldImage, newImage, 10)
offset =
32 -1
function offset = detectOffset(oldImage, newImage, margin)
if size(oldImage) ~= size(newImage)
offset = [];
error('Test images must be the same size.');
end
[imageHeight, imageWidth] = size(oldImage);
corr = zeros(2 * imageHeight - 1, 2 * imageWidth - 1);
for yIndex = [1:2*imageHeight-1; ...
imageHeight:-1:1 ones(1, imageHeight-1); ...
imageHeight*ones(1, imageHeight) imageHeight-1:-1:1];
oldImage = circshift(oldImage, [1 0]);
for xIndex = [1:2*imageWidth-1; ...
imageWidth:-1:1 ones(1, imageWidth-1); ...
imageWidth*ones(1, imageWidth) imageWidth-1:-1:1];
oldImage = circshift(oldImage, [0 1]);
numPoint = abs(yIndex(3) - yIndex(2) + 1) * abs(xIndex(3) - xIndex(2) + 1);
corr(yIndex(1),xIndex(1)) = sum(sum(oldImage(yIndex(2):yIndex(3),xIndex(2):xIndex(3)) .* newImage(yIndex(2):yIndex(3),xIndex(2):xIndex(3)))) * imageHeight * imageWidth / numPoint;
end
end
[value, yOffset] = max(corr(margin+1:end-margin,margin+1:end-margin));
[dummy, xOffset] = max(value);
offset = [yOffset(xOffset)+margin-imageHeight xOffset+margin-imageWidth];