原文鏈接:http://www.juzicode.com/archives/5399
在OpenCV-Python中圖像表示成numpy數組,圖像的屬性也可以通過numpy的屬性獲得。
1、圖像行列數、通道數(shape屬性)
一個圖像像素的行列數(高、寬)、通道數可以通過shape屬性獲取,需要注意的是numpy數組的shape屬性下標0表示的圖像的行數(rows,高),下標1表示的是列數(cols,寬),下標2表示的是通道數,但是如果是灰度圖shape是一個二元組,則不存在下標2的元素。
import numpy as np
import cv2
print('VX公眾號: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
img = cv2.imread('..\\opencv-logo.png')
print('img.shape',img.shape)
rows = img.shape[0]
cols = img.shape[1]
channel = img.shape[2]
print('rows=%d,cols=%d,channel=%d'%(rows,cols,channel))
cv2.imshow('juzicode.com',img)
cv2.waitKey()
#原圖方式
img = cv2.imread('..\\opencv-logo.png',cv2.IMREAD_UNCHANGED)
print('img.shape',img.shape)
rows = img.shape[0]
cols = img.shape[1]
channel = img.shape[2]
print('rows=%d,cols=%d,channel=%d'%(rows,cols,channel))
cv2.imshow('juzicode.com',img)
cv2.waitKey()
#灰度圖方式
img = cv2.imread('..\\opencv-logo.png',cv2.IMREAD_GRAYSCALE)
print('img.shape',img.shape)
rows = img.shape[0]
cols = img.shape[1]
channel = img.shape[2] #這里拋異常
print('rows=%d,cols=%d,channel=%d'%(rows,cols,channel))
cv2.imshow('juzicode.com',img)
cv2.waitKey()
運行結果:
VX公眾號: 桔子code / juzicode.com
cv2.__version__: 4.5.2
img.shape (739, 600, 3)
rows=739,cols=600,channel=3
img.shape (739, 600, 4)
rows=739,cols=600,channel=4
img.shape (739, 600) #轉換為灰度圖,shape是一個二元組,訪問下標2導致拋異常
Traceback (most recent call last):
File "img-properties.py", line 37, in <module>
channel = img.shape[2]
IndexError: tuple index out of range
另外我們也可以用Windows的畫圖板程序打開原圖看到圖像得行列數,其行數(rows,高,y軸)為739對應了shape[0],列數(cols,寬,x軸)為600對應了shape[1]:
對比C++版本的OpenCV,可以直接訪問Mat的rows、cols屬性和channels()方法獲取到圖像的寬高以及通道數:
2、nbytes、size、itemsize屬性
在OpenCV-Python對外接口里圖像用numpy數組表示,所以numpy數據的屬性同樣適用於OpenCV-Python中圖像的屬性,詳情可參考 NumPy數組的屬性和常用創建方法。
下面的例子中仍是通過3種不同方式獲取圖像后對比各個屬性的例子:
import numpy as np
import cv2
print('VX公眾號: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
img = cv2.imread('..\\opencv-logo.png')
print('img.ndim=',img.ndim) #維度,也是其shape屬性的長度=len(shape)
print('img.itemsize=',img.itemsize) #單個數據長度
print('img.size=',img.size) #總長度,有多少個數據
print('img.nbytes=',img.nbytes) #占用的內存空間=itemsize*size
print('img.dtype=',img.dtype) #數據類型,字符串形式
print('img.shape=',img.shape) #形狀,是一個tuple
print('img.data=',img.data) #數據buffer
print()
#原圖方式
img = cv2.imread('..\\opencv-logo.png',cv2.IMREAD_UNCHANGED)
print('img.ndim=',img.ndim) #維度,也是其shape屬性的長度=len(shape)
print('img.itemsize=',img.itemsize) #單個數據長度
print('img.size=',img.size) #總長度,有多少個數據
print('img.nbytes=',img.nbytes) #占用的內存空間=itemsize*size
print('img.dtype=',img.dtype) #數據類型,字符串形式
print('img.shape=',img.shape) #形狀,是一個tuple
print('img.data=',img.data) #數據buffer
print()
#灰度圖
img = cv2.imread('..\\opencv-logo.png',cv2.IMREAD_GRAYSCALE)
print('img.ndim=',img.ndim) #維度,也是其shape屬性的長度=len(shape)
print('img.itemsize=',img.itemsize) #單個數據長度
print('img.size=',img.size) #總長度,有多少個數據
print('img.nbytes=',img.nbytes) #占用的內存空間=itemsize*size
print('img.dtype=',img.dtype) #數據類型,字符串形式
print('img.shape=',img.shape) #形狀,是一個tuple
print('img.data=',img.data) #數據buffer
運行結果:
VX公眾號: 桔子code / juzicode.com
cv2.__version__: 4.5.2
img.ndim= 3
img.itemsize= 1
img.size= 1330200
img.nbytes= 1330200
img.dtype= uint8
img.shape= (739, 600, 3)
img.data= <memory at 0x000002D0D8793E50>
img.ndim= 3
img.itemsize= 1
img.size= 1773600
img.nbytes= 1773600
img.dtype= uint8
img.shape= (739, 600, 4)
img.data= <memory at 0x000002D0D8793E50>
img.ndim= 2
img.itemsize= 1
img.size= 443400
img.nbytes= 443400
img.dtype= uint8
img.shape= (739, 600)
img.data= <memory at 0x000002D0F2D026C0>
3、dtype屬性
dtype屬性描述的是numpy數組中數據類型,可以通過astype進行轉換后看到dtype的變化,以及因為dtype變化引起itemsize相關屬性的變化。
下面這個例子讀出opencv-logo.png圖像后再轉換為np.uint32和np.float64:
import numpy as np
import cv2
print('VX公眾號: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
img = cv2.imread('..\\opencv-logo.png')
print('img.ndim=',img.ndim) #維度,也是其shape屬性的長度=len(shape)
print('img.itemsize=',img.itemsize) #單個數據長度
print('img.size=',img.size) #總長度,有多少個數據
print('img.nbytes=',img.nbytes) #占用的內存空間=itemsize*size
print('img.dtype=',img.dtype) #數據類型,字符串形式
print('img.shape=',img.shape) #形狀,是一個tuple
print('img.data=',img.data) #數據buffer
#轉換
print('轉換為uint32')
img = img.astype(np.uint32)
print('img.ndim=',img.ndim) #維度,也是其shape屬性的長度=len(shape)
print('img.itemsize=',img.itemsize) #單個數據長度
print('img.size=',img.size) #總長度,有多少個數據
print('img.nbytes=',img.nbytes) #占用的內存空間=itemsize*size
print('img.dtype=',img.dtype) #數據類型,字符串形式
print('img.shape=',img.shape) #形狀,是一個tuple
print('img.data=',img.data) #數據buffer
#轉換
print('轉換為float64')
img = img.astype(np.float64)
#print(img[150:200,200:250])
print('img.ndim=',img.ndim) #維度,也是其shape屬性的長度=len(shape)
print('img.itemsize=',img.itemsize) #單個數據長度
print('img.size=',img.size) #總長度,有多少個數據
print('img.nbytes=',img.nbytes) #占用的內存空間=itemsize*size
print('img.dtype=',img.dtype) #數據類型,字符串形式
print('img.shape=',img.shape) #形狀,是一個tuple
print('img.data=',img.data) #數據buffer
運行結果:
VX公眾號: 桔子code / juzicode.com
cv2.__version__: 4.5.2
img.ndim= 3
img.itemsize= 1
img.size= 1330200
img.nbytes= 1330200 ##=size*itemsize=1330200*1
img.dtype= uint8
img.shape= (739, 600, 3)
轉換為uint32
img.ndim= 3
img.itemsize= 4
img.size= 1330200
img.nbytes= 5320800 ##=size*itemsize=1330200*4
img.dtype= uint32
img.shape= (739, 600, 3)
轉換為float64
img.ndim= 3
img.itemsize= 8
img.size= 1330200
img.nbytes= 10641600 ##=size*itemsize=1330200*8
img.dtype= float64
img.shape= (739, 600, 3)
從運行結果看單個元素占用空間itemsize和總空間大小nbytes均發生了變化。
小結:因為圖像在OpenCV-Python是以numpy數組形式表示的,圖像的屬性比如行列數、通道數、數據類型、size等相關屬性都可以通過numpy屬性獲取。
原文鏈接:http://www.juzicode.com/archives/5399