I successfully create and fill a matrix with depth and RGB data from the Kinect V2 libfreenect2 library like so:
cv::Mat(registered.height, registered.width, CV_8UC4, registered.data).copyTo(cpu_depth);
cv::imshow("depth", cpu_depth);
I believe this matrix is equivilent to [X,Y,Z,R,G,B,A] for each point within the image. How do I access the unsigned char values within the matrix?
I have tried like this:
uchar xValue = cpu_depth.at(cv::Point(20, 20))[0];
but it doesn't compile and I feel I am missing something very obvious.
I figured it out. You need to state that you have 4 bytes per chanel with a cast. So to correctly access points within the matrix you do this:
uchar xValue = cpu_depth.at<cv::Vec4b>(cv::Point(20, 20))[0];
This matrix is NOT equivalent to [X,Y,Z,R,G,B,A] for each point. This matrix is 2-dimensional array of cv::Vec4b elements (i. e. cv::Vec<uchar, 4> elements - one uchar element per channel). Each element can be (R, G, B, A) or (x, y, z, val) or something else - it's just 4 values at position (x, y).
Thus for access element in position (x, y) for desired channel you can use the following options:
cpu_depth.at<cv::Vec4b>(cv::Point(x, y))[channel] - get channel value at point (x, y);
cpu_depth.at<cv::Vec4b>(y, x)[channel] - get channel value at point (x, y) - matrix first index is row, that's why firstly y and then x;
*(cpu_depth.ptr<uchar>(y) + 4 * x + channel) - value of pointer in y-th row and x-th column, i. e. at position (x, y).
Related
The following is a more elaborative conjecture on what i wish to achieve; here is how far I reached;
A 3d grid, about 303030, or a 3d array, so i can define a function of R3 -> R f(x, y, z) = v More precisely, where x, y, z € [0, N] of float values so for f(0.5, 0.5, 0.5) the result would be the trilinear interpolation for the points (0,0,0), (0,0,1), (0,1,0), (0,1,1), (1,0,0), (1,0,1), (1,1,0) and (1,1,1). With v is equal to the value stored in the array if x, y, and z are integer values, or the trilinear interpolation of the closest points in the array where N_i is the number of points - 1 in the i dimension of the array; x € [0, N_x], y € [0, N_y], and z € [0, N_z]. Now let's Imagine a 1d array(which does not exist, only integer indices), one can make up a value by interpolation between closest actual values, and can extend this to 2d, though if you try to get a value for the position 0.3864 for positions 0 and 1 you need the 4 closest points in the end you can extend to any number of dimensions. Providing the values at (0,0), (0,1), (1,0) and (1,1). n is the number of dimensions which have a non-integer coordinate, but you get the point with a bilinear interpolation, and you'll need exactly 2n points where n is the number of dimensions.
Simplified;
I have a 3d grid of floats which via I wish to access this values in parallel by the thousands In random positions. To which then I want to convert this memory bound process into cpu bound; by flattening the 3d array, and approximate it with a finite Fourier expansion or something similar. Then calculate the values at the required positions of this flattened data and use the calculated values to do the trilinear interpolation. Conclusively, the original code would just access the values by their array indices, one by one. as the values are being accessed randomly and they are far away from each other in memory; which i'm looking for a suitable strategy to access (or calculate if possible) the values based on an index.
Here is my reasoning:
openGL draws everything within a 2x2x2 cube
the x,y values inside this cube determine where the point is drawn on the screen. The z value is used for other stuff...
if you want the z value to have some effect on perspective you need to mutate the scene (usually with a matrix) so that it gives an illusion of distant objects being smaller.
the z values of the cube go from -1 to 1.
Now I want it so that objects that are at z = 1 are infinitely zoomed, and objects that are at z = 0 are normal size, and objects that are at z = -1 are 1/2 size.
When I say an object is zoomed, I mean that the (x,y) coordinates of its points are multiplied by scaler zoom factor, which is based on its z coordinate.
If a point lies outside the 2x2x2 cube I want the calculations to still be done on it if it is between z = 1 and z = -1. Since the z value doesn't change I don't care what happens to any points that are not within this range, as long as their z value is not changed.
Generalized point transformation:
If I have a point P = (x, y, z), and -1 <= z <= 1 then:
the Zoom Factor, S = 1 / (1 - z)
so the translation is as follows:
(x, y, z) ==> (x * S, y * S, z)
Creating the matrix?
This is where I am having issues. I don't know how to create a matrix so that it will transform a generalized point to have the desired effect.
I am considering not using a matrix and applying this transformation via a function in glsl...
If someone has insight on how to create such a matrix I would like to know.
I have object A, with a speed. Speed is specified as 3D vector a = (x, y, z). Position is 3D point A [X, Y, Z]. I need to find out, if the current speed leads this object to another object B on position B [X, Y, Z].
I've sucessfully implemented this in 2 dimensions, ignoring the third one:
/*A is projectile, B is static object*/
//entity is object A
// - .v[3] is the speed vector
//position[3] is array of coordinates of object B
double vector[3]; //This is the vector c = A-B
this->entityVector(-1, entity.id, vector); //Fills the correct data
double distance = vector_size(vector); //This is distance |AB|
double speed = vector_size(entity.v); //This is size of speed vector a
float dist_angle = (float)atan2(vector[2],vector[0])*(180.0/M_PI); //Get angle of vector c as seen from Y axis - using X, Z
float speed_angle = (float)atan2((double)entity.v[2],entity.v[0])*(180.0/M_PI); //Get angle of vector a seen from Y axis - using X, Z
dist_angle = deg180to360(dist_angle); //Converts value to 0-360
speed_angle = deg180to360(speed_angle); //Converts value to 0-360
int diff = abs((int)compare_degrees(dist_angle, speed_angle)); //Returns the difference of vectors direction
I need to create the very same comparison to make it work in 3D - right now, the Y positions and Y vector coordinates are ignored.
What calculation should I do to get the second angle?
Edit based on answer:
I am using spherical coordinates and comparing their angles to check if two vectors are pointing in the same direction. With one vector being the A-B and another A's speed, I'me checking id A is heading to B.
I'm assuming the "second angle" you're looking for is φ. That is to say, you're using spherical coordinates:
(x,y,z) => (r,θ,φ)
r = sqrt(x^2 + y^2 + z^2)
θ = cos^-1(z/r)
φ = tan^-1(y/x)
However, if all you want to do is find if A is moving with velocity a towards B, you can use a dot product for a basic answer.
1st vector: B - A (vector pointing from A to B)
2nd vector: a (velocity)
dot product: a * (B-A)
If the dot product is 0, it means that you're not getting any closer - you're moving around a sphere of constant radius ||B-A|| with B at the center. If the dot product > 0, you're moving towards the point, and if the dot product < 0, you're moving away from it.
I have an array that represents a grid
For the sake of this example we will start the array at 1 rather that 0 because I realized after doing the picture, and can't be bothered to edit it
In this example blue would have an index of 5, green an index of 23 and red 38
Each color represents an object and the array index represents where the object is. I have implemented very simple gravity, whereby if the grid underneath is empty x + (WIDTH * (y + 1)) then the grid below is occupied by this object, and the grid that the object was in becomes empty.
This all works well in its current form, but what I want to do is make it so that red is the gravity point, so that in this example, blue will move to array index 16 and then 27.
This is not too bad, but how would the object be able to work out dynamically where to move, as in the example of the green grid? How can I get it to move to the correct index?
Also, what would be the best way to iterate through the array to 'find' the location of red? I should also note that red won't always be at 38
Any questions please ask, also thank you for your help.
This sounds very similar to line rasterization. Just imagine the grid to be a grid of pixels. Now when you draw a line from the green point to the red point, the pixels/cells that the line will pass are the cells that the green point should travel along, which should indeed be the shortest path from the green point to the red point along the discrete grid cells. You then just stop once you encounter a non-empty grid cell.
Look for Bresenham's algorithm as THE school book algorithm for line rasterization.
And for searching the red point, just iterate over the array linearly until you have it and then keep track of its grid position, like William already suggested in his answer.
x = x position
y = y position
cols = number of columns across in your grid
(y * cols) + x = index in array absolute value for any x, y
you could generalize this in a function:
int get_index(int x, int y, int gridcols)
{
return (gridcols * y) + x;
}
It should be noted that this works for ZERO BASED INDICES.
This is assuming I am understanding what you're talking about at all...
As for the second question, for any colored element you have, you should keep a value in memory (possibly stored in a structure) that keeps track of its position so you don't have to search for it at all.
struct _THING {
int xpos;
int ypos;
};
Using the get_index() function, you could find the index of the grid cell below it by calling like this:
index_below = get_index(thing.x, thing.y + 1, gridcols);
thing.y++; // increment the thing's y now since it has moved down
simple...
IF YOU WANT TO DO IT IN REVERSE, as in finding the x,y position by the array index, you can use the modulus operator and division.
ypos = array_index / total_cols; // division without remainder
xpos = array_index % total_cols; // gives the remainder
You could generalize this in a function like this:
// x and y parameters are references, and return values using these references
void get_positions_from_index(int array_index, int total_columns, int& x, int& y)
{
y = array_index / total_columns;
x = array_index % total_columns;
}
Whenever you're referring to an array index, it must be zero-based. However, when you are referring to the number of columns, that value will be 1-based for the calculations. x and y positions will also be zero based.
Probably easiest would be to work entirely in a system of (x,y) coordinates to calculate gravity and switch to the array coordinates when you finally need to lookup and store objects.
In your example, consider (2, 4) (red) to be the center of gravity; (5, 1) (blue) needs to move in the direction (2-5, 4-1) == (-3, 3) by the distance _n_. You get decide how simple you want n to be -- it could be that you move your objects to an adjoining element, including diagonals, so move (blue) to (5-1, 1+1) == (4, 2). Or perhaps you could move objects by some scalar multiple of the unit vector that describes the direction you need to move. (Say, heavier objects move further because the attraction of gravity is stronger. Or, lighter objects move further because they have less inertia to overcome. Or objects move further the closer they are to the gravity well, because gravity is an inverse square law).
Once you've sorted out the virtual coordinates of your universe, then convert your numbers (4, 2) via some simple linear formulas: 4*columns + 2 -- or just use multidimensional arrays and truncate your floating-point results to get your array indexes.
I know this may sound stupid but I'm goin crazy with this XD
I'm loading ad image (with ImageMagick) into a 1D vector, so that I have something like:
012345678...
RGBRGBRGB...
Where 0-. Are obviously the indexes of the vector, and R, G, and B are respectively the red byte, green byte, and blue byte.
So I have a WIDTHxHEIGHTx3 bytes vector.
Now, let's say I want to access the x,y,z byte, where z is the index of the color, which is the transformation formula to have a linear offset into the vector?
This expression produces an index to color component z at pixel (x,y):
((y * WIDTH) + x) * 3 + z
Assumptions are:
Data is placed in row-major order.
No padding/alignment bytes are used between rows.
Assuming your data is stored as a series of rows (not a crazy assumption), you can find byte x,y,z at y*WIDTH*3 + 3*x + z