OpenCV-Python教程:圖像屬性(高寬,通道,size,數據類型)


原文鏈接:http://www.juzicode.com/archives/5399

返回Opencv-Python教程

在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

 

擴展閱讀:

  1. OpenCV-Python教程
  2. NumPy數組的屬性和常用創建方法


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM