Python/Numpy Contiguousness Error (Bug #2100)


Added by Kyle Horn over 12 years ago. Updated about 12 years ago.


Status:Done Start date:2012-06-27
Priority:High Due date:
Assignee:Vadim Pisarevsky % Done:

0%

Category:python bindings
Target version:2.4.3
Affected version: Operating System:
Difficulty: HW Platform:
Pull request:

Description

So I've recently installed OpenCV (via the most recent windows pre-built installation), and have been playing around with the python bindings.

I noticed when trying to implement and test the ANN_MLP python class that there's a subtle error that only appears when the second argument of ANN_MLP.predict() is Fortran contiguous, rather than C contiguous. I've attached copies of two scripts: one working and one dysfunctional. The only difference is how the variablie "z" is initialized.

This bug is easy to miss, as one-dimensional numpy arrays are both C and Fortran contiguous by default, whereas multidimensional arrays may vary based on the method of instantiation.

The quick-and-dirty fix would be just to force the second argument of MLP_ANN.predict(inputs,outputs) to be C contiguous, like so:
outputs = array(outputs,order='c')

The problem is that this bug probably exists for most or all python binding functions that take a Numpy array for output. A better fix would involve changing how C manipulates Numpy array data. If you access each member of a Numpy array's read-write buffer through strides while in C, then the continuity of the array is irrelevant.

If the latter is the preferred fix by the OpenCV team, and no one on the team is familiar with how to access Numpy stride values, and use them to properly index multidimensional Numpy arrays in C, then I could give a more detailed explanation in a followup post, as this post is already running long.

I set the priority of this bug to high under the assumption that it's endemic to many functions in the Python bindings. If I'm in error, then my sincerest apologies. Feel free to downgrade its priority if appropriate. Cheers.


failing.py - When 'output', the 2nd arg of ANN_MLP.predict() is Fortran contiguous, the function fails to copy results to 'output'. (2.6 kB) Kyle Horn, 2012-06-27 02:52 am

working.py - When 'output', the 2nd arg of ANN_MLP.predict() is C contiguous, the function works as intended. (2.3 kB) Kyle Horn, 2012-06-27 02:52 am


Associated revisions

Revision 0adf68ae
Added by Alexander Mordvintsev over 12 years ago

work on #2100: pyopencv_to functions now can receive argument information through ArgInfo structure. Non-contiguous input numpy arrays are copied. In case of non-contiguous output array the TypeError is thrown.

Revision d652cc72
Added by Vadim Pisarevsky over 12 years ago

fixed bugs #2100 (kind of) and #1393

[edit: cleaned whitespace]

History

Updated by Alexander Mordvintsev over 12 years ago

Fixed in r0adf68ae. Following behaviour is implemented:
Most OpenCV functions treat arrays as "row-contiguous" (step[ndim-1] == elemsize). If non-row-contiguous NumPy array is passed to OpenCV function, it is either implicitly copied (for input arrays), or TypeError is thrown (for out and in/out arrays).

  • Status changed from Open to Done

Updated by Andrey Kamaev over 12 years ago

  • Target version set to 2.4.3

Updated by Alexander Mordvintsev over 12 years ago

Reopened. Partially broken in rev. ff90c3eb.
No check for row-contiguous for multichannel arrays:

import numpy as np
import cv2

a = np.zeros((100, 100, 3))
b = a[:, ::2]  # not row-contiguous !!!
cv2.circle(b, (20, 20), 20, (0, 255, 0)) # should fail here
cv2.imshow('a', a)
cv2.waitKey()

  • Status changed from Done to Open

Updated by Vadim Pisarevsky over 12 years ago

  • Target version deleted (2.4.3)
  • Assignee deleted (Vadim Pisarevsky)

Updated by Andrey Kamaev over 12 years ago

  • Assignee set to Vadim Pisarevsky
  • Status changed from Open to Done

Updated by Andrey Kamaev about 12 years ago

  • Target version set to 2.4.3

Also available in: Atom PDF