Numpy incorrect dot product when filling - numpy

I am having some trouble with numpy dot product - the product of a rotation matrix & a vector. Please see code. The two lines should give the same result! Where I am storing the result of the calculation should not affect the calculation. Y should be the same as y1 and y2.
import numpy
rotMat = numpy.array([[-0.27514947, 0.40168313, 0.87346633], [ 0.87346633, -0.27514947, 0.40168313], [ 0.40168313, 0.87346633, -0.27514947]])
print "Rotation matrix:"
print rotMat
x = [1, 0, 1, 1, 1, 0]
X = numpy.array(x)
X.shape = (2, 3)
Y = numpy.array(6*[0])
Y.shape = (2, 3)
print "X", X
print "Y initialised:", Y
Y[0, :] = numpy.dot(rotMat, X[0, :])
Y[1, :] = numpy.dot(rotMat, X[1, :])
print "Filling Y initialised, Y=", Y
print "not filling Y initialised:"
print "y1", numpy.dot(rotMat, X[0, :])
print "y2", numpy.dot(rotMat, X[1, :])
Which gives result:
Rotation matrix: [[-0.27514947 0.40168313 0.87346633]
[ 0.87346633 -0.27514947 0.40168313]
[ 0.40168313 0.87346633 -0.27514947]]
X [[1 0 1]
[1 1 0]]
Y initialised: [[0 0 0]
[0 0 0]]
Filling Y initialised, Y= [[0 1 0]
[0 0 1]]
not filling Y initialised:
y1 [ 0.59831686 1.27514946 0.12653366]
y2 [ 0.12653366 0.59831686 1.27514946]
I am using Python 2.7.11, with Numpy 1.10.1

You are filling in Y which is of type int and therefore converts all values placed into it to int. When initializing Y, initialize as float.
Y = numpy.array(6*[0], float)
per #hpaulj's comment:
Y = numpy.zeros((6,))
will also work because the default dtype is float

Related

Numpy: Filter list of 2D indices by 2D mask

I am having a numpy array of 2D points data (x, y, other_properties), where x and y are integer pixel coordinates. Additionally, I am having a binary 2D segmentation mask mask. I would like to filter the list, to obtain only the points where the mask is one/true.
I thought about doing something like:
valid_indices = np.argwhere(mask_2D)
to then filter the data based on the valid indices and I would like to do that using numpy acceleration.
Here is a toy example
# the data representing x and y coordinates
data = np.arange(10).reshape((5, 2))
data = np.concatenate((data, data), axis=0)
print(f"data: {data}")
# Let's say we already obtained the indices from the segmentation mask
valid_indices = [(6, 7), (0, 1)]
print(f"valid_indices: {valid_indices}")
filtered = []
for point in data:
if tuple(point) in valid_indices:
filtered.append(tuple(point))
filtered = np.array(filtered)
print(f"filtered: {filtered}")
Output:
data:
[[0 1]
[2 3]
[4 5]
[6 7]
[8 9]
[0 1]
[2 3]
[4 5]
[6 7]
[8 9]]
valid_indices:
[(6, 7), (0, 1)]
filtered:
[[0 1]
[6 7]
[0 1]
[6 7]]
Process finished with exit code 0
Is there a way to obtain the behavior above using numpy? The solution could also directly use the binary 2D segmentation mask. If not, do you have any suggestions how to speed up the process?
Thank you!
You can do it with broadcast compare,
data[(data == np.array(valid_indices)[:,None]).all(-1).any(0)]

Expand matrix based on vector

I want to turn matrix A into matrix B.
Is there a better/more efficient approach with NumPy than the following?
import numpy as np
a = np.array([[0.02, 0.05, 0.05],
[0.35, 0.10, 0.45],
[0.08, 0.25, 0.15]])
w = np.array([0.75, 0.25])
B = np.insert(a, 9, a[2, :]).reshape(4, 3)
B = np.insert(B.T, 12, B[:, 2]).reshape(4, 4).T
B[2:4, :] = np.multiply(B[2:4, :].T, w).T
.insert isn't a good choice here because numpy needs to allocate memory to create a whole new array every time you do so. Instead, just pre-allocate the size of array you need, and then assign to its slices.
a = np.array([[0.02, 0.05, 0.05],
[0.35, 0.10, 0.45],
[0.08, 0.25, 0.15]])
w = np.array([0.75, 0.25])
b_shape = tuple(s + 1 for s in a.shape) # We need one more row and column than a
b = np.zeros(b_shape) # Create zero array of required shape
b[:a.shape[0], :a.shape[1]] = a # Set a in the top left corner
b[:, -1] = b[:, -2] # Set last column from second-last column
b[-1, :] = b[-2, :] # Set last row from second-last row
b[-w.shape[0]:, :] = b[-w.shape[0]:, :] * w[:, None] # Multiply last two rows with `w`
w[:, None] makes w a column vector (a 2x1 matrix), and numpy broadcasts the shapes to do the correct elementwise multiplication.
This gives us the required b:
array([[0.02 , 0.05 , 0.05 , 0.05 ],
[0.35 , 0.1 , 0.45 , 0.45 ],
[0.06 , 0.1875, 0.1125, 0.1125],
[0.02 , 0.0625, 0.0375, 0.0375]])
Putting this in a function to compare runtimes against your approach:
import numpy as np
import timeit
from matplotlib import pyplot as plt
#% Define functions
def func_insert(a, w):
B = np.insert(a, a.size, a[-1, :]).reshape(a.shape[0]+1, a.shape[1])
B = np.insert(B.T, B.size, B[:, -1]).reshape(a.shape[0]+1, a.shape[1]+1).T
B[-w.shape[0]:, :] = np.multiply(B[-w.shape[0]:, :].T, w).T
return B
def func_prealloc(a, w):
b_shape = tuple(s + 1 for s in a.shape)
b = np.zeros(b_shape)
b[:a.shape[0], :a.shape[1]] = a
b[:, -1] = b[:, -2]
b[-1, :] = b[-2, :]
b[-w.shape[0]:, :] = b[-w.shape[0]:, :] * w[:, None]
return b
#% Time function calls
sizes = [3, 10, 50, 100, 500, 1000, 5000, 10_000]
times = np.zeros((len(sizes), 2))
for i, size in enumerate(sizes):
a = np.random.random((size, size))
w = np.random.random((2,))
times[i, 0] = timeit.timeit("func_insert(a, w)", globals=globals(), number=10) / 10
print(".")
times[i, 1] = timeit.timeit("func_prealloc(a, w)", globals=globals(), number=10) / 10
print("x")
#% Plot results
fig, ax = plt.subplots()
ax.plot(sizes, times[:, 0], label="Insert")
ax.plot(sizes, times[:, 1], label="Prealloc")
ax.set_xscale('log')
ax.set_yscale('log')
ax.legend()
ax.set_xlabel('Array size (NxN)')
ax.set_ylabel('Time per function call (s)')
ax.grid(True)
fig.tight_layout()
]
There's a consistent 3-5x speedup by preallocating.

I can't get same point with homography matrix reverse transform

I get invert of homography matrix
self.inv_homography = np.linalg.inv(self.homography)
and my trasnform function
def doTransform(x, y, homography):
p = np.ndarray(shape=(3, 1), dtype=float, order='F')
p[0, 0] = x
p[1, 0] = y
p[2, 0] = 1
res = np.dot(homography, p)
return res
but third row is not same with first row, there is some pixel slip
ref coords :(768, 512, 1024, 768)
ref to wa coords: 569.5178327464915 185.9395922739289 790.8947327112375 448.7356913249636
wa to ref coords: 767.149391928569 510.19931575332294 1022.283053230326 764.3653307505839
how do I fix this slip ?
I think that you have hardcoded the z coordinate might be the problem. If the z coordinate does not transform to exactly 1, you will introduce an error. This code returns the expected output:
import numpy as np
def transform(x, y, z, homography):
p = np.array([x,y,z]).reshape(3,1)
return np.dot(homography, p)
hom = np.array([1.2,3.1, 4.0, 2.4, 5.4, 3.2, 1.1, 3.0, 1.2]).reshape(3,3)
x, y, z = 2.3, 1.7, 1
inv_hom = np.linalg.inv(hom)
x_wa = transform(x, y, z, hom)[0, 0]
y_wa = transform(x, y, z, hom)[1, 0]
z_wa = transform(x, y, z, hom)[2, 0]
print(transform(x_wa, y_wa, z_wa, inv_hom))
>>[[2.3]
[1.7]
[1. ]]

How to compare two different tensors through matplotlib or any other visualize tools?

I have two tensors x and y, there both are the same dimension shape = (1, 64, 1, 1)
basically y is output from many functions, and x is the input
I want to compare these two tensor using visualize tool like matplotlib..etc
anyway to do ?
The below are x and y example, I only post 10 of 64 since the restriction
x
tensor([[[[-0.8467]],
[[-0.0949]],
[[-0.8253]],
[[-0.1027]],
[[ 0.0476]],
[[-0.4173]],
[[-0.0870]],
[[ 0.0650]],
[[ 0.3816]],
[[ 0.2046]]]], grad_fn=<MulBackward0>)
y
tensor([[[[-2.0307]],
[[-0.1594]],
[[-1.5174]],
[[-0.2767]],
[[ 0.1049]],
[[-0.9605]],
[[-0.2127]],
[[ 0.1342]],
[[ 0.8275]],
[[ 2.0508]],
]])
You can convert x and y to numpy arrays and then use whatever matplotlib function you want
with torch.no_grad():
x_np = x.cpu().numpy()[0, :, 0, 0] # make it 1d
y_np = y.cpu().numpy()[0, :, 0, 0]
plt.plot(x_np - y_np)
plt.show()

Extract triangles form delaunay filter in mayavi

How can I extract triangles from delaunay filter in mayavi?
I want to extract the triangles just like matplotlib does
import numpy as np
import matplotlib.delaunay as triang
from enthought.mayavi import mlab
x = np.array([0, 1, 2, 0, 1, 2, 0, 1, 2])
y = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2])
z = np.zeros(9)
#matplotlib
centers, edges, triangles_index, neig = triang.delaunay(x,y)
#mayavi
vtk_source = mlab.pipeline.scalar_scatter(x, y, z, figure=False)
delaunay = mlab.pipeline.delaunay2d(vtk_source)
I want to extract the triangles from mayavi delaunay filter to obtain the variables #triangle_index and #centers (just like matplotlib)
The only thing I've found is this
http://docs.enthought.com/mayavi/mayavi/auto/example_delaunay_graph.html
but only get the edges, and are codificated different than matplotlib
To get the triangles index:
poly = delaunay.outputs[0]
tindex = poly.polys.data.to_array().reshape(-1, 4)[:, 1:]
poly is a PolyData object, poly.polys is a CellArray object that stores the index information.
For detail about CellArray: http://www.vtk.org/doc/nightly/html/classvtkCellArray.html
To get the center of every circumcircle, you need to loop every triangle and calculate the center:
centers = []
for i in xrange(poly.number_of_cells):
cell = poly.get_cell(i)
points = cell.points.to_array()[:, :-1].tolist()
center = [0, 0]
points.append(center)
cell.circumcircle(*points)
centers.append(center)
centers = np.array(centers)
cell.circumcircle() is a static function, so you need to pass all the points of the triangle as arguments, the center data will be returned by modify the fourth argument.
Here is the full code:
import numpy as np
from enthought.mayavi import mlab
x = np.array([0, 1, 2, 0, 1, 2, 0, 1, 2])
y = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2])
z = np.zeros(9)
vtk_source = mlab.pipeline.scalar_scatter(x, y, z, figure=False)
delaunay = mlab.pipeline.delaunay2d(vtk_source)
poly = delaunay.outputs[0]
tindex = poly.polys.data.to_array().reshape(-1, 4)[:, 1:]
centers = []
for i in xrange(poly.number_of_cells):
cell = poly.get_cell(i)
points = cell.points.to_array()[:, :-1].tolist()
center = [0, 0]
points.append(center)
cell.circumcircle(*points)
centers.append(center)
centers = np.array(centers)
print centers
print tindex
The output is:
[[ 1.5 0.5]
[ 1.5 0.5]
[ 0.5 1.5]
[ 0.5 0.5]
[ 0.5 0.5]
[ 0.5 1.5]
[ 1.5 1.5]
[ 1.5 1.5]]
[[5 4 2]
[4 1 2]
[7 6 4]
[4 3 1]
[3 0 1]
[6 3 4]
[8 7 4]
[8 4 5]]
The result may not be the same as matplotlib.delaunay, because there are many possible solutions.