More details to come, but I was comparing the performance of OpenCV to Matlab Computer Vision Toolbox for the dense estimates of optical flow given by the Horn Schunck algorithm. I was getting a very different result with OpenCV vs. Matlab for the Optical Flow Estimation. It seemed that OpenCV was washing out fine details in the optical flow. After carefully comparing Matlab Computer Vision and OpenCV outputs for Horn Schunck optical flow, I found that the default lambda/smoothness parameter of 1.0 for cv.CalcOpticalFlowHS is not the same as what Matlab calls 1.0.
I need to quantify this further, but for now I found that in OpenCV cv.CalcOpticalFlowHS setting lambda=0.001 gives results that are much more like Matlab–I can see the fine details. This is just a rough guess, if I have time I’ll quantify it in my forthcoming article on segmenting terabtyes of aurora borealis video in an hour!
import numpy as np
A = np.matrix(np.random.randn(5000,5000))
B = np.matrix(np.random.randn(5000,5000))
1 loops, best of 3: 2.51 s per loop
Matlab R2014b, also with Intel MKL A = randn(5000,5000);
B = randn(5000,5000);
f = @() A*B;
So, Numpy is about twice as fast as Matlab at this matrix multiplication.
example 2: Using Numba in iterative algorithms.
from numba import jit # inline auto compilation to C of Python code
from time import time
from numpy import diff
def f(): # declare a function
for i in range(int(1e7)): #generator much faster than arange here!
x = 0.5*x + i % 10
tic = time()
print('elapsed time (sec)',time()-tic)
elapsed time (sec) 0.07639932632446289
tic, x = 0; for i = 0:1e7-1; x = 0.5*x + mod(i,10); end, toc
Elapsed time is 0.608442 seconds.
Python is 7.96 times faster than Matlab for this trivial test.
You can also find plenty of examples where Python is somewhat slower than Matlab. For me the places where Python was much faster seemed to very much outweigh the slower places.
First of all, you can’t pass sparse matrices, so you have to have enough RAM to hold the full matrix and probably a copy or two of it. This is more just to show how it could be done, and hope that the Mathworks will improve the passing of variables in future releases of Matlab.
All commands are issued in Matlab R2014b.
a = eye(5);
A = py.numpy.reshape(a(:)',size(a));
As = py.scipy.sparse.csc_matrix(A)
As noted in my earlier post, this is awkward because Matlab doesn’t understand Numpy arrays. Matlab understands lists, dicts, sets, scalars, and other less frequently used classes from Python. Let’s do an example with the “clown” image included with Matlab. All commands here are executed in Matlab R2014b.
First off, here are some Python packages that don’t currently work from Matlab R2014b (just hard crash Matlab)
cv2 (opencv 2.4)
NOTE: The use of the ‘F’ parameter to and from Python in the .reshape() and .ravel() methods–this is crucial or your matrix will be transposed inside Python!
load clown % 200x320 image is now in variable X
Xp = py.numpy.reshape(X(:)',size(X),'F'); % I ravel X to a row vector, and unravel with Numpy
Yp = py.scipy.ndimage.gaussian_filter(Xp,3); % SciPy works, but Scikit-image doesn't for me
% now let's come back to Matlab
Y = reshape(cell2mat(cell(Yp.ravel('F').tolist())),size(X)); % a regular Matlab 2-D matrix
imshow(Y,map) %map comes from when you load clown
% now let's do something similar in Matlab--note I didn't make the filter truncation radius the same, so the numerical results differ.
F = fspecial('gaussian',[15,15],3);
M = imfilter(X,F);
Of course normally you would be using Python for a function not readily available in Matlab, but this was a side-by-side working example.
Initially it appears that to use OpenCV from Matlab R2014b, you will need to write your OpenCV calls in C++, using all the usual Mex stuff. This is not very convenient to me; it would be much more convenient to use the friendly syntax of Python. However the Python support in Matlab R2014b allows passing only 1xN arrays, so there would be reshaping involved to/from Python that would slow things down.
The mexopencv package that has been available for some time (and that works with earlier versions of Matlab) seems to be more user-friendly once installed–you use it much like any other Matlab toolbox, without you needing to code in C++/Mex yourself.
Bottom line: I’ll still be using Python/OpenCV without Matlab, or even C++/OpenCV, which looks easier than using Mex with Matlab. I am glad Mathworks has taken this step; maybe the mexopencv people will make the R2014b OpenCV support easier to use by making a bunch of .cpp functions to compile once and then call.
Note that for Matlab 2014b, which is the first version of Matlab to have official support for Python, you can only to TO python a 1xN vector. You have to reshape the matrix into a 1xN vector when passing the matrix into Python, and reshape back to a matrix inside Python, but I think Matlab will make copies at both reshapings.
Note that Numpy ndarrays are not understandable by Matlab, you will have to make your Numpy array into a 1-D list and then send it back. Yikes that’s a lot of memory copying!
I can pass py.numpy.sqrt(2)
ans=[ 1.41421356 1.41421356]
but I cannot pass py.numpy.sqrt([2,2;2,2]) Error using py.numpy.sqrt Conversion of MATLAB 'double' to Python is only supported for 1-N vectors.
the link below seems to confirm that you cannot pass normal 2D matrices to Python from Matlab R2014b:
Currently, Octave 3.8.1 in Cygwin64 was compiled with headers 1.8.12 but HDF5 library 1.8.13.
This causes Octave to seg fault Warning! ***HDF5 library version mismatched error*** and exit.
To avoid having to recompile, you can type HDF5_DISABLE_VERSION_CHECK=1 octave
to startup octave
you can perhaps add to your ~/.bashrc file the line: alias octave="HDF5_DISABLE_VERSION_CHECK=1 octave -q"