理解numpy的axis

研究numpyaxis,是因为使用cv2时,图片数据都是以ndarray存储的,然后为了对其中的矩阵数据进行解析、处理(比如局部马赛克),就需要对axis有所了解。

首先看看cv2读取图片信息后是啥东东:

cv2.imread(/path/to/image, flag)

对于flag的取值:

  • cv2.IMREAD_COLOR 读取图片的RGB信息,忽略透明度(Alpha)的channel,按照BGR这3个channel的次序返回numpy.ndarray;若调用imread时,没有设置flag的话,flag默认取这个值
  • cv2.IMREAD_GRAYSCALE 只返回灰度图像信息,每一个元素的下标可以理解为(y, x)
  • cv2.IMREAD_UNCHANGED 按照原图像信息返回。如果为RGB图像,按照BGR这3个channel的次序返回numpy.ndarray;如果为ARGB,按照BGRA这4个channel的次序返回numpy.ndarray

对于ARGB或者RGB,每一个元素的下标可以理解为[y, x, channel]:

  • [:, :, 0] Blue channel
  • [:, :, 1] Green channel
  • [:, :, 2] Red channel
  • [:, :, 3] Alpha channel,即 Transparency channel

将BGR转为RGB:

img_rgb = img_bgr[:,:,::-1]

数据参考:

>>> img_bgr = cv2.imread(‘./01.png’)

>>> img_gray = cv2.imread(‘./01.png’, cv2.IMREAD_GRAYSCALE)

>>> img_ori = cv2.imread(‘./01.png’, cv2.IMREAD_UNCHANGED)

>>> img_bgr.shape

(564, 790, 3)

>>> img_gray.shape

(564, 790)

>>> img_ori.shape

(564, 790, 4)

>>> img_bgr

array([[[ 24, 21, 20],

    [ 24,  21,  20],

    [ 24,  21,  20],

    ...,

    [ 24,  21,  20],

    [ 24,  21,  20],

    [ 24,  21,  20]],



   [[ 24,  21,  20],

    [255, 255, 255],

    [255, 255, 255],

    ...,

    [255, 255, 255],

    [255, 255, 255],

    [ 24,  21,  20]],



   [[ 24,  21,  20],

    [255, 255, 255],

    [255, 255, 255],

    ...,

    [255, 255, 255],

    [255, 255, 255],

    [ 24,  21,  20]],



   ...,



   [[ 24,  21,  20],

    [ 69,  41,  34],

    [ 68,  40,  33],

    ...,

    [251, 248, 245],

    [249, 246, 242],

    [ 24,  21,  20]],



   [[ 24,  21,  20],

    [ 24,  21,  20],

    [ 24,  21,  20],

    ...,

    [ 24,  21,  20],

    [ 24,  21,  20],

    [ 24,  21,  20]],



   [[ 24,  21,  20],

    [ 24,  21,  20],

    [ 24,  21,  20],

    ...,

    [ 24,  21,  20],

    [ 24,  21,  20],

    [ 24,  21,  20]]], dtype=uint8)

>>> img_gray

array([[ 21, 21, 21, …, 21, 21, 21],

   [ 21, 255, 255, ..., 255, 255,  21],

   [ 21, 255, 255, ..., 255, 255,  21],

   ...,

   [ 21,  43,  43, ..., 248, 245,  21],

   [ 21,  21,  21, ...,  21,  21,  21],

   [ 21,  21,  21, ...,  21,  21,  21]], dtype=uint8)

>>> img_ori

array([[[ 24, 21, 20, 255],

    [ 24,  21,  20, 255],

    [ 24,  21,  20, 255],

    ...,

    [ 24,  21,  20, 255],

    [ 24,  21,  20, 255],

    [ 24,  21,  20, 255]],



   [[ 24,  21,  20, 255],

    [255, 255, 255, 255],

    [255, 255, 255, 255],

    ...,

    [255, 255, 255, 255],

    [255, 255, 255, 255],

    [ 24,  21,  20, 255]],



   [[ 24,  21,  20, 255],

    [255, 255, 255, 255],

    [255, 255, 255, 255],

    ...,

    [255, 255, 255, 255],

    [255, 255, 255, 255],

    [ 24,  21,  20, 255]],



   ...,



   [[ 24,  21,  20, 255],

    [ 69,  41,  34, 255],

    [ 68,  40,  33, 255],

    ...,

    [251, 248, 245, 255],

    [249, 246, 242, 255],

    [ 24,  21,  20, 255]],



   [[ 24,  21,  20, 255],

    [ 24,  21,  20, 255],

    [ 24,  21,  20, 255],

    ...,

    [ 24,  21,  20, 255],

    [ 24,  21,  20, 255],

    [ 24,  21,  20, 255]],



   [[ 24,  21,  20, 255],

    [ 24,  21,  20, 255],

    [ 24,  21,  20, 255],

    ...,

    [ 24,  21,  20, 255],

    [ 24,  21,  20, 255],

    [ 24,  21,  20, 255]]], dtype=uint8)

如果暂不看cv2使用cv2.IMREAD_COLOR读取后的数据,单纯看numpy.ndarray,从一维到三维数据,会是这样:

numpy.ndarray的axis

而通过cv2读取的图片数据,每一个元素的下标可以理解为[y, x, channel],对于flagcv2.IMREAD_COLOR时,读取后的数据为*(B, G, R)*,每个像素可以通过[y, x, :]进行获取,其axis分析如下:

cv2.imread下图片数据的axis