How to check dimensions of a numpy array?
numpy.array.shape is a tuple of array dimensions. You can compute the length of a tuple and that will give the number of dimensions.
if len(image.shape) == 2: return image # this image is grayscaleelif len(image.shape) == 3: return image # image is either RGB or YCbCr colorspace
Numpy arrays also have a ndim
attribute.
if image.ndim == 2: return image # this image is grayscaleelif image.ndim == 3: return image # image is either RGB or YCbCr colorspace
THERE IS ONE MORE "hidden-DIMENSION" OF THE PROBLEM :
Numpy has a few performance-motivated tricks, that may confuse you, if not taking due care of:
There are tricks that np.view()
creates, as a view into a "foreign"-owned data, which actually means there has appeared a form of hidden sharing, which may pretty ugly surprise you if some operations on already "return()
-ed" image
store any modification into a just-.view()
-created view. In such cases your code will silently damage the "foreign"-data, because you did not realise or notice that while the image
reports correctly both the image.{shape|ndim}
, yet it does not "have" its own data, but provides just a view through a "periscope-alike-window" into the original data, still "owned" somewhere else by someone else ( here, a write into image
, like in an exemplary assignment of image[0,0] = -1
will actually "write-through" the -1
to get it stored into the "throat" of A
-s A.data
, being actually a <read-write buffer for 0x7efe9ff73800, size 7372800, offset 0 at 0x7efe9ff6cbf0>
implementor-zone of the actual write-storage operation resulting in modification taking place in A
's data )
This side-effect of .view()
-s is both very powerful (if used knowingly, where intended, for performance or other reasons) yet also very awful to detect/debug (if not detected in the code design phase and just hunting the devils tail once the "source"-data get damaged without knowing who does turned the so far clear and sound design wreck havoc "foreign&safely-owned"-data from behind a curtain ... that may take and indeed takes pretty long to detect such hidden sharing write-throughs ... if they take place without your prior intent )
>>> A = np.arange( 3*640*480 ).reshape( 3, 640, 480 )>>> A.shape(3, 640, 480)>>> A.ndim3>>> B = A.view() # ENFORCE B BECOME A VIEW() ON AN ARRAY>>> B.shape # B MIMICS AN ARRAY, WHILE IT IS NOT AN ARRAY(3, 640, 480)>>> B.ndim # B MIMICS AN ARRAY, WHILE IT IS NOT AN ARRAY3>>> B.flags # B MIMICS AN ARRAY, WHILE IT IS NOT AN ARRAY C_CONTIGUOUS : True F_CONTIGUOUS : False OWNDATA : False <------------------- a view() on array, not the array itself WRITEABLE : True ALIGNED : True WRITEBACKIFCOPY : False UPDATEIFCOPY : False>>> image = B[0,:,:] # slice B into an IMAGE, which will still look as if it is an array>>> image.flags C_CONTIGUOUS : True F_CONTIGUOUS : False OWNDATA : False <----------------- a view() onto an array, not the array itself WRITEABLE : True ALIGNED : True WRITEBACKIFCOPY : False UPDATEIFCOPY : False>>> image.ndim2>>> image.shape(640, 480)
Hope you will enjoy the .view()
-s, where used for performance or other reasons and hope you will never have to back-track the hidden-sharing side-effects in production.