I have a vector field that is defined in a 2D plane. This means that the Z component of the position is constant, but vectors are 3D. I have plotted this using quiver3 as below:
[X,Y] = meshgrid(-pi/2:pi/8:pi/2,-pi/2:pi/8:pi/2);
Z=ones(size(X));
U=rand(size(X));
V=rand(size(X));
W=rand(size(X));
H=quiver3(X,Y,Z,U,V,W,'r');
H.ShowArrowHead = 'off';
The above code does the job, but it does not look good. Is it possible to represent the vector field like the below picture with 3D rods?
Related
I have several pairs of images + cloud of 3D points that correspond to the same view. There are no rules for the change of coordinates. Everything is stored in a table.
Rows : image x coordinate
Columns : image y coordinate
Cell: 3D points (x,y,z) coordinates.
Practically, this is a NumPy array of dimensions (1920, 1080, 3).
The other way around, finding the coordinate of the 3D point when you have the coordinate in the image is pretty straightforward.
def image_to_xyz(self,image_points):
"""
Takes a point in the image
Return corresponding xyz coordinates
"""
xyz = self.xyz
image_points_x = image_points[:,0]
image_points_y = image_points[:,1]
xyz_points = xyz[image_points_x,image_points_y]
return xyz_points
For the other way around, it is easy, but dirty, to make a for loop and search for a corresponding point with a precision threshold. I tried it.
It's in python, I can't use Julia, so the loop took several minutes to complete. Way too much...
Do you have better suggestions?
Thanks
We know that we can plot 3d graphs in MatPlotLib but in which field does it used and for what purpose
3D graphs are used when you need to establish the relationship between 3 variables(x,y and z).
This application can be used in the following fields:
1)geographical area: In this field X,Y is used as latitude,longitude and Z can be used as Altitude to replicate the geographical area like hills,buildings etc..
2)Geometry: To visualize the 3d objects like plane,sphere,cube etc in three dimensional space we use 3d plotting.
3)Statistics: To compare two variables on third variable we use 3d plots like 3d barchart, Scatter plot etc..
There are many other fields where 3d plotting is used instead of 2d plot, as it provides more information visually.
When you are working with 3 variables and want to plot a graph in between them and identify the relationship between them then you should use 3d graphs.
There can be many use cases of 3d plots:
To describe the position of a point in a plane if the position varies with time, we now need 3 measurements- x-axis distance, y-axis distance, and time elapsed.
To describe the position of a point in 3D space, we need 3 measurements: x distance, y distance and z distance.
To describe the position of a point in 3D space, if the position varies with time, we need 4 measurements: x distance, y distance, z distance and time.
Each of those measurements represents a dimension, and each dimension requires it’s own axis.
Follow this docs for more information
I am currently working on eeg signals, so here basically we have electrodes which are placed on head of a person and we get 3d coordinates of each electrodes so basically i am trying to find 2d coordinates from these 3d coordinates but with the help of equirectangular projection ( the same way how we project globe on a plane paper).
Here are the few links for better understanding:
https://www.earthdatascience.org/courses/use-data-open-source-python/intro-vector-data-python/spatial-data-vector-shapefiles/geographic-vs-projected-coordinate-reference-systems-python/
https://www.coursera.org/lecture/introduction-gis-mapping/associating-points-from-3d-to-2d-y7kIx
https://mathworld.wolfram.com/MercatorProjection.html
I think it should be the following but maybe you can confirm if this is correct:
import math
def cartesian_to_spherical(x,y,z):
r=math.sqrt(x**2+y**2+z**2)
theta=math.acos(z/r)
phi=math.atan(y/x)
return r,theta,phi
def spherical_to_mercator(r,theta,phi):
x=theta
y=0.5*math.log((1+math.sin(phi))/(1-math.sin(phi)))
return x,y
r,theta,phi=cartesian_to_spherical(2,3,1) # fill in your x,y,z here
x,y=spherical_to_mercator(r,theta,phi)
print("x = ",x," y = ",y)
the below code transforms a detected 2D-image point to it's 3D location on a defined plane Grid in 3D-world.
This mean Z=0, and taking into account that the Extrinsics and Intrinsics are known, we can compute the corresponding 3D_point of the detected 2D-image point:
import cv2
import numpy as np
#load extrinsics & intrinsics
with np.load('parameters_cam1.npz') as X:
mtx, dist = [X[i] for i in ('mtx','dist','rvecs','tvecs')]
with np.load('extrincic.npz') as X:
rvecs1,tvecs1 = [X[i] for i in('rvecs1','tvecs1')]
#prepare rotation matrix
R_mtx, jac=cv2.Rodrigues(rvecs1)
#prepare projection matrix
Extrincic=cv2.hconcat([R_mtx,tvecs1])
Projection_mtx=mtx.dot(Extrincic)
#delete the third column since Z=0
Projection_mtx = np.delete(Projection_mtx, 2, 1)
#finding the inverse of the matrix
Inv_Projection = np.linalg.inv(Projection_mtx)
#detected image point (extracted from a que)
img_point=np.array([pts1_blue[0]])
#adding dimension 1 in order for the math to be correct (homogeneous coordinates)
img_point=np.vstack((img_point,np.array(1)))
#calculating the 3D point which located on the 3D plane
3D_point=Inv_Projection.dot(img_point)
#show results
print('3D_pt_method1\n',3D_point)
#output
3D_pt_method1
[[0.01881387]
[0.0259416 ]
[0.04150276]]
By normalizing the point (dividing by the third value) the result is
`X_World=0.45331611680765327 # 45.3 cm from defined world point cm which is correct
Y_world=0.6250572251098481 # 62.5 cm which is also correct
By evaluating the results, it turns out that they are correct.
I now that we can't retrieve the the Z coordinate of the 3D world point since depth information is lost going from 3d to 2d. The following equation also performs the inverse projection of the 2D point onto 3D world and can be found in all literature, and the result is an equation which represents a line on which the 3D_ world point must lie on
I put the equation 3.15 into code, however without setting Z=0, meaning to say with out deleting the third column of the projection matrix like i did in the previous method (Just as it's written) by doing the following the following:
#inverting the rotation matrix
INV_R=np.linalg.inv(R_mtx)
#inverting the camera matrix
INV_k=np.linalg.inv(mtx)
#multiplying the tow matrices
kinv_Rinv=INV_k.dot(INV_R)
#calcuating the 3D_point X which expressed in eq.3.15
3D_point=kinv_Rinv.dot(img_point)+tvecs1
#print the results
print('3D_pt_method2\n',3D_point)
and the result was
3D_pt_method2 #how should one understand these coordinates ?
[[-9.12505825]
[-5.57152147]
[40.12264881]]
My question is, How should i understand or interpret this result? as it doesn't make any sense compared to the previous method where Z=0. the 3D 3x1 resulted vector seems to give an intuition that it's values represents simply the 3D X, Y and Z of the detected image_point. However, this is not true if we compare X and Y with the previous method!!
So what is literally the difference between 3D_pt_method1 and 3D_pt_method2???
I hope i could express my self and really appreciate helping me understand the difference between the two implementations!
Note: the Grid that represents my defined World-plane and can be seen in the below image in which the distance between every two yellow points is 40 cm
Thanks in advance
You miss the key variable "w" in method2.
You can get help from referring to this article: https://blog.csdn.net/zhou4411781/article/details/103876478
This article is written in Chinese, but you can just try to get the point from those formula in that article if you cannot understand Chinese.
Simply speaking:
You said right "I know that we can't retrieve the the Z coordinate of the 3D world point since depth information is lost going from 3d to 2d. "
This also means: If you know the depth (the Z axis value in world coordination), you can get 3d ordinate by 2d ordinate and the depth. As well, if you know the X or Y axis value in world coordination, you can also get the result.
Essentially I am trying to do a Fermi Surface plot, in 2D. i.e. a 2D cut of f(n,vec_k)=e_f for some plane in K-space, with interpolation. Specifically, I have a numpy array: Eigen, with shape,
Eigen.shape = (100,100,100,10), where the first three indices are over the vector vec_k, and the third is the band index 'n'. How to get a cut through an arbitrary surface Eigen == e_f, where e_f is a scalar number?
This is generally solved using a marching cube algorithm. You should look into contour3d() function of MLab here: http://docs.enthought.com/mayavi/mayavi/auto/mlab_helper_functions.html#mayavi.mlab.contour3d. THis does exactly what you want.
contour3d(Eigen[:,:,:, bandNo], contours=e_f)
should do it for you. You can also specify a number of surfaces for all bands like so:
for bandNo in range(totalBands):
contour3d(Eigen[:,:,:, bandNo], contours=[eF1, eF2, eF3], opacity=0.4)
You should get plots like these: http://docs.enthought.com/mayavi/mayavi/_images/enthought_mayavi_mlab_contour3d1.jpg