Showing posts with label python3. Show all posts
Showing posts with label python3. Show all posts

Friday, 7 August 2015

Matlab's repmat in Python

This post is partly to remind myself of this, partly for others who might find themselves in a similar situation. I find myself wanting to use a repmat function in Python - used as I am to Matlab's syntax. A quick search will tell you that the function to use is numpy.tile, and that's indeed true.

But, say that you have an image of shape (1024,512) and you'd like it to become (1024,512,3). What's the way to go? In Matlab you would just say

B = repmat(A,[1,1,3]);

and if you try that with np.tile you'll find that B has shape (1,1024,1536). Somehow, it's added a new dimension at the beginning, not at the end!

To obtain the same behaviour as Matlab, you have to do

B = np.tile(A.reshape(1024,512,1), (1,1,3))

In practice you're explicitly adding a dimension to the array A before tiling it.

Having said that, numpy does something that Matlab doesn't: it broadcasts operators. So if you have two arrays of different dimensions, numpy can automatically repeat the same operation (a bit like Matlab's bsxfun). The catch is that the operation is repeated over the first dimension of the array. So let's say we want to add A of shape (1024,512) and B of shape (1024,512,3). The way I'd go about doing that is with transposes:

C = A.T + B.T
C = C.T

Transposition in numpy is more generic than in Matlab and can be applied to n-dimensional arrays. It changes the dimensions so that that an array of size w,x,y,z its transpose will have size z,y,x,w. So that's now adding matrices of shapes (512,1024) and (3,512,1024), which works because the broadcasting happens along the first dimension. Then, of course, the result needs to be transposed back.

Wednesday, 29 July 2015

Compiling OpenCV on Yosemite

I found myself wanting to use some OpenCV features from Python. But I prefer to use Python 3, which made the Homebrew distribution of OpenCV almost useless - as the version coming with Homebrew doesn't support it. The only option was then compiling OpenCV 3.0.0. Here's how I went about doing it.

For the following, I'm assuming you're using Python 3.4.3 coming with Homebrew. Note that future updates might break the compilation, so proceed with care. Also, the OpenCV distribution that comes with Homebrew mustn't be installed or you'll have problem linking this one later.

The first step is downloading OpenCV 3.0.0 - using git works just as well as downloading the zip file.

git https://github.com/Itseez/opencv.git
cd opencv
mkdir release
cd release

Now I'm assuming you'd like to keep your installation tidy, and the best way is to let Homebrew handle this. The next command will let you configure the compilation, and to do so you will have to set some variables. The command to launch is

ccmake ..

You need to fill in the following variables:

CMAKE_INSTALL_PREFIX/usr/local/Cellar/opencv/3.0.0
PYTHON2_EXECUTABLE/usr/local/bin/python3.4
PYTHON3_EXECUTABLE/usr/local/bin/python3.4
PYTHON3_INCLUDE_DIR/usr/local/Frameworks/ Python.framework/Versions/3.4/ include/python3.4m
PYTHON3_LIBRARY/usr/local/Frameworks/ Python.framework/Versions/3.4/ lib/libpython3.4.dylib
PYTHON3_NUMPY_INCLUDE_DIRS/usr/local/lib/python3.4/site-packages/numpy/core/include
PYTHON3_PACKAGES_PATH/usr/local/lib/python3.4/site-packages

Now, CMAKE_INSTALL_PREFIX is what will later allow Homebrew to handle your installation of OpenCv. Also, you might notice that PYTHON2_EXECUTABLE is actually set to Python 3. For reasons beyond me, without that it doesn't look the Python bindings are compiled correctly so, well, whatever works.

At this point, you can check that cmake is happy with what you've done with Python. To do so, first of all, save your configuration by pressing <C> from the keyboard, and then <Q>. Then, just type

cmake ..

and you should see the following:

--   Python 2:
--     Interpreter:                 /usr/local/bin/python3.4 (ver 3.4.3)
--
--   Python 3:
--     Interpreter:                 /usr/local/bin/python3 (ver 3.4.3)
--     Libraries:                   /usr/local/Frameworks/Python.framework/Versions/3.4/lib/libpython3.4.dylib (ver 3.4.3)
--     numpy:                       /usr/local/lib/python3.4/site-packages/numpy/core/include (ver 1.9.2)
--     packages path:               /usr/local/lib/python3.4/site-packages
--
--   Python (for build):            /usr/local/bin/python3.4

This way you should be confident that the compilation process will generate all your Python bindings. And now we go with the usual

make
make install

and of course, to make sure that Homebrew will take care of your installation,

brew link opencv

If you want to make sure that the Python binding has been compiled, you should find the file lib/python3/cv2.so inside your release directory.

And finally, one little catch. Keep in mind that this cv2.so will end up inside your python site-packages, i.e., outside the reach of Homebrew. An alternative might be to set PYTHON3_PACKAGES_PATH somewhere inside the Cellar, and then add it to your PYTHONPATH variable, but I don't know if that will work or not.