Numpy and inverse matrices - method to do only one reshape instruction - python-2.7

I am doing a batch execution of high number of 3x3 matrices with CUDA.
The goal is to get a big matrix of 3x3 matrix (so I use a 4D array).
I have done previously the same operation with numpy.linalg.inv function. With this way, I can directly get an array of 3x3 matrix : I show you the code that performs this operation.
Now, with CUDA version, I would like to reshape in a minimum of instructions the big 1D array produced : so I have to build a (N,N,3,3) array from a (NN3*3) 1D array.
For the moment, I can do this reshape into 2 steps (here the code below).
The original version with classical numpy.linalg.inv is carried out by:
for r_p in range(N):
for s_p in range(N):
# original version (without GPU)
invCrossMatrix[:,:,r_p,s_p] = np.linalg.inv(arrayFullCross_vec[:,:,r_p,s_p])
invCrossMatrix represents a (3,3,N,N) array and I get it directly from the (3,3,N,N) arrayFullCross array (dimBlocks = 3)
For the moment, when I use GPU batch execution, I start from the 1D array :
# Declaration of inverse cross matrix
invCrossMatrix_temp = np.zeros((N**2,3,3))
# Create arrayFullCross_vec array
arrayFullCross_vec = np.zeros((3,3,N,N))
# Create arrayFullCross_vec array
invCrossMatrix_gpu = np.zeros((3*3*(N**2)))
# Build observables covariance matrix
arrayFullCross_vec = buildObsCovarianceMatrix3_vec(k_ref, mu_ref, ir)
## Performing batch inversion 3x3 :
invCrossMatrix_gpu = gpuinv3x3(arrayFullCross_vec.flatten('F'),N**2)
## First reshape
invCrossMatrix_temp = invCrossMatrix_gpu.reshape(N**2,3,3)
# Second reshape : don't forget ".T" transpose operator
invCrossMatrix = (invCrossMatrix_temp.reshape(N,N,3,3)).T
Question 1) Why the -F option into flatten('F') is necessary?
If I do only gpuinv3x3(arrayFullCross_vec.flatten,N**2), the code doesn't work. Python is maybe column major like Fortran ?
Question 2) Now, I would like to convert the following block:
## First reshape
invCrossMatrix_temp = invCrossMatrix_gpu.reshape(N**2,3,3)
# Second reshape : don't forget ".T" transpose operator
invCrossMatrix = (invCrossMatrix_temp.reshape(N,N,3,3)).T
into a single reshape instruction. Is it possible?
The issue is about to convert the 1D array invCrossMatrix_gpu(N**2 * 3 *3) directly into a (3,3,N,N) array.
I expect to reshape the original 1D array in one only time since I call these routines a lot of times.
Update
Is to right to say that array inVCrossMatrix defined by:
invCrossMatrix = (invCrossMatrix_temp.reshape(N,N,3,3)).T
has dimensions (3,3,N,N).
#hpaulj: Is it equivalent to do this?
invCrossMatrix =(invCrossMatrix_temp.reshape(N,N,3,3)).transpose(2,3,0,1)

Related

Optimal way to append to numpy array when dealing with large dimensions

I am working with a json file that consists of approximately 17,000 3x1 arrays denoting the coordinates.
Currently,I have an image of 1024x1024 dimensions(which I have flattend),and I am using np.hstack to add the 3x1 array to that image ,this gives me a 1d array of dimension 1048579x1
My objective is to create a final array of dimension 1048579x17,000.
Unfortunately list.append and np.append are not working in this case,because it's consuming too much memory.I tried running this on colab pro,but the memory consumption is too high which causes the session to crash
My current code is as follows
image=cv2.imread('image_name.jpg',0)
shape=image.shape
flat_img=image.ravel()
print(flat_img.shape)
#Here data consists of 17,000 entries each of which is a 3x1 list
with open('data.json') as f:
json1_str = f.read()
json1_data=json.loads(json1_str)
local_coordinates=[]
for i in range(len(json1_data)):
local_coord=json1_data[i]['local_coordinate']
local_coord=np.array(local_coord)
new_arr=np.hstack((flat_img,local_coord))
new_arr=new_arr.tolist()
local_coordinates.append(new_arr) #
Is there an optimal way to stack all the 1048579 1d arrays to create the final matrix which can be used for training purposes?

How to reshape Tensor in C++ like Caffe's Blob

I want to use tensors of dynamic shapes in C++. For example, I want add a new op in tensorflow, but I do not know the output's shape in the beginning. If I use Caffe, I can firstly reshape the output blob to the maximum size I will use, and reshape to it is actual size in the end.
How can do it with tensorflow's Tensor?.
If you are not sure about the shape of your Variable yet, leave one or more dimension of that tf.Variable as None. For example:
x = tf.placeholder(tf.float32, shape=[None, 1,1])
Tensorflow also has a tf.reshape() function that you can use in the same fashion as caffe. For example:
x2 = tf.reshape(x, [-1, dim]) # -1 means "all"

building an array or matrix from stdin

I'm trying to build an array / matrix from a command given through stdin. The command is formatted like this:
nameOfArray build numberOfDimensions : dimensionList : valueList
Another example:
B build 1 : 3 : 4,5,6
The command needs to work for up to three dimensions, and I am completely stumped as to how to implement it.
Since we are limited to three dimensions, the problem is easy. We simply treat all the cases as the 3 dimensional case, with height and depth set to one for the lower dimensions.
So we set up the array with malloc() or std::vector::resize() width * height * depth, then read the values in one by one. In C, the job is done. In C++, you might then need to fiddle about to turn your vector into a multi-dimensional matrix class with a nice interface.

How to implemet 1D convolution in opencv?

Is there any way to implement convolution of 1D signal in OpenCV?
As I can see there is only filter2D, but I'm looking for something like Matlab's convn.
For 1-D convolutions, you might want to look at np.convolve.
See here: https://docs.scipy.org/doc/numpy/reference/generated/numpy.convolve.html
Python OpenCV programs that need a 1-D convolution can use it readily.
You can always view a 1D vector as a 2D mat, and thus simply calling the opencv build-it functions resolves the problem.
Below is a snippet that I use to smooth an image histogram.
# Inputs:
# gray = a gray scale image
# smoothing_nbins = int, the width of 1D filter
# Outputs:
# hist_sm = the smoothed image histogram
hist = cv2.calcHist([gray],[0],None,[256],[0,256])
hist_sm = cv2.blur(hist, (1, smoothing_nbins))
As you can see, the only trick you need here is to set one filter dimension to 1.
As far as I know, if you use convolve2D with just the 1D matrix, it still works. But depending on your specific work, it may not.

Examples of Matlab to OpenCV conversions

From time to time I have to port some Matlab Code to OpenCV.
Almost always there is a way to do it and an appropriate function in OpenCV. Nevertheless its not always easy to find.
Therefore I would like to start this summary to find and gather some equivalents between Matlab and OpenCV.
I use the Matlab function as heading and append its description from Matlab help. Afterwards a OpenCV example or links to solutions are appreciated.
Repmat
Replicate and tile an array. B = repmat(A,M,N) creates a large matrix B consisting of an M-by-N tiling of copies of A. The size of B is [size(A,1)*M, size(A,2)*N]. The statement repmat(A,N) creates an N-by-N tiling.
B = repeat(A, M, N)
OpenCV Docs
Find
Find indices of nonzero elements. I = find(X) returns the linear indices corresponding to the nonzero entries of the array X. X may be a logical expression. Use IND2SUB(SIZE(X),I) to calculate multiple subscripts from the linear indices I.
Similar to Matlab's find
Conv2
Two dimensional convolution. C = conv2(A, B) performs the 2-D convolution of matrices A and B. If [ma,na] = size(A), [mb,nb] = size(B), and [mc,nc] = size(C), then mc = max([ma+mb-1,ma,mb]) and nc = max([na+nb-1,na,nb]).
Similar to Conv2
Imagesc
Scale data and display as image. imagesc(...) is the same as IMAGE(...) except the data is scaled to use the full colormap.
SO Imagesc
Imfilter
N-D filtering of multidimensional images. B = imfilter(A,H) filters the multidimensional array A with the multidimensional filter H. A can be logical or it can be a nonsparse numeric array of any class and dimension. The result, B, has the same size and class as A.
SO Imfilter
Imregionalmax
Regional maxima. BW = imregionalmax(I) computes the regional maxima of I. imregionalmax returns a binary image, BW, the same size as I, that identifies the locations of the regional maxima in I. In BW, pixels that are set to 1 identify regional maxima; all other pixels are set to 0.
SO Imregionalmax
Ordfilt2
2-D order-statistic filtering. B=ordfilt2(A,ORDER,DOMAIN) replaces each element in A by the ORDER-th element in the sorted set of neighbors specified by the nonzero elements in DOMAIN.
SO Ordfilt2
Roipoly
Select polygonal region of interest. Use roipoly to select a polygonal region of interest within an image. roipoly returns a binary image that you can use as a mask for masked filtering.
SO Roipoly
Gradient
Approximate gradient. [FX,FY] = gradient(F) returns the numerical gradient of the matrix F. FX corresponds to dF/dx, the differences in x (horizontal) direction. FY corresponds to dF/dy, the differences in y (vertical) direction. The spacing between points in each direction is assumed to be one. When F is a vector, DF = gradient(F)is the 1-D gradient.
SO Gradient
Sub2Ind
Linear index from multiple subscripts. sub2ind is used to determine the equivalent single index corresponding to a given set of subscript values.
SO sub2ind
backslash operator or mldivide
solves the system of linear equations A*x = B. The matrices A and B must have the same number of rows.
cv::solve