Reason
這兩天學習OpenCV-Python時,也就是cv2庫,讀取圖像時不時出現和預料之外的結果。于是作者從源頭來考究一下cv2.imread(filename, flags)
Result
這裡參考文章cv2.imread(filename, flags)
cv2.imread(filename, flags)
參數:
filepath:讀入imge的完整路徑
flags:标志位,{cv2.IMREAD_COLOR,cv2.IMREAD_GRAYSCALE,cv2.IMREAD_UNCHANGED}
cv2.IMREAD_COLOR:預設參數,讀入一副彩色圖檔,忽略alpha通道,可用1作為實參替代
cv2.IMREAD_GRAYSCALE:讀入灰階圖檔,可用0作為實參替代
cv2.IMREAD_UNCHANGED:顧名思義,讀入完整圖檔,包括alpha通道,可用-1作為實參替代
PS:alpha通道,又稱A通道,是一個8位的灰階通道,該通道用256級灰階來記錄圖像中的透明度複資訊,定義透明、不透明和半透明區域,其中黑表示全透明,白表示不透明,灰表示半透明
Experiemt
這裡用到的兩個img:MyPic.png,MyPicGray.png
![]() | |
當然需要先導入cv2,并接下來會使用的一個自定義fun()
import cv2
# ouput img properties
def funOutputImgProperties(img):
print("properties:shape:{},size:{},dtype:{}".format(img.shape,img.size,img.dtype))
首先對彩色圖MyPic測試:imread分别以三種flag讀取MyPic,并輸出圖像參數:
代碼如下:
# 3 channels img loads
# 讀入完整圖檔,含alpha通道
img3ChaCom = cv2.imread('MyPic.png', cv2.IMREAD_UNCHANGED)
cv2.imshow('IMREAD_UNCHANGED+Color',img3ChaCom)
cv2.waitKey()
funOutputImgProperties(img3ChaCom)
# 讀入彩色圖檔,忽略alpha通道
img3Cha=cv2.imread('MyPic.png',cv2.IMREAD_COLOR)
cv2.imshow('IMREAD_COLOR+Color', img3Cha)
cv2.waitKey()
funOutputImgProperties(img3Cha)
#彩色圖檔按,灰階圖檔讀入
img3ChaGray=cv2.imread('MyPic.png',cv2.IMREAD_GRAYSCALE)
cv2.imshow('IMREAD_GRAYSCALE+Color', img3ChaGray)
cv2.waitKey()
funOutputImgProperties(img3ChaGray)
輸出資訊:
視窗圖像
| | |
控制台輸出:
properties:shape:(500, 500, 3),size:750000,dtype:uint8
properties:shape:(500, 500, 3),size:750000,dtype:uint8
properties:shape:(500, 500),size:250000,dtype:uint8
和作者預想的一樣,IMREAD_UNCHANGED和IMREAD_COLOR标志位的img讀取自然是3 channels彩圖,而使用IMREAD_GRAYSCALE标志位時,imread将彩色圖像直接讀取為灰色,B\G\R的三通道變成了單通道。圖檔像素改變:500X500X3->500X500X1
接下來,考察灰階圖MyPicGray:imread分别以三種flag讀取MyPic,并輸出圖像參數:
代碼如下:
# 1 channel img loads
# 讀入完整圖檔,含alpha通道
img1ChaCom = cv2.imread('MyPicGray.png', cv2.IMREAD_UNCHANGED)
cv2.imshow('IMREAD_UNCHANGED+Gray', img1ChaCom)
cv2.waitKey()
funOutputImgProperties(img1ChaCom)
# 讀入彩色圖檔,忽略alpha通道
img1ChaColor = cv2.imread('MyPicGray.png', cv2.IMREAD_COLOR)
cv2.imshow('IMREAD_COLOR+Gray', img1ChaColor)
cv2.waitKey()
funOutputImgProperties(img1ChaColor)
# 彩色圖檔按,灰階圖檔讀入
img1Cha = cv2.imread('MyPicGray.png', cv2.IMREAD_GRAYSCALE)
cv2.imshow('IMREAD_GRAYSCALE+Gray', img1Cha)
cv2.waitKey()
funOutputImgProperties(img1Cha)
輸出資訊:
視窗圖像
| | |
控制台輸出:
properties:shape:(500, 500),size:250000,dtype:uint8
properties:shape:(500, 500, 3),size:750000,dtype:uint8
properties:shape:(500, 500),size:250000,dtype:uint8
結合輸出圖像和控制台輸出我們可以看到,三個imgshow的輸出都是展現的灰階圖,但是imread的flag為IMREAD_COLOR時,圖像實際上時三通道的彩色圖。
進一步的,我們直接輸出IMREAD_COLOR+Gray和IMREAD_GRAYSCALE+Gray的像素矩陣。可以看到IMREAD_COLOR+Gray确實時三通道的[ [ [ ] ] ]像素矩陣,IMREAD_GRAYSCALE+Gray是[ [ ] ]。
[[[246 246 246]
[246 246 246]
[246 246 246]
...
[246 246 246]
[246 246 246]
[246 246 246]]
[[246 246 246]
[246 246 246]
[246 246 246]
...
[246 246 246]
[246 246 246]
[246 246 246]]
[[246 246 246]
[246 246 246]
[246 246 246]
...
[246 246 246]
[246 246 246]
[246 246 246]]
...
[[246 246 246]
[246 246 246]
[246 246 246]
...
[246 246 246]
[246 246 246]
[246 246 246]]
[[246 246 246]
[246 246 246]
[246 246 246]
...
[246 246 246]
[246 246 246]
[246 246 246]]
[[246 246 246]
[246 246 246]
[246 246 246]
...
[246 246 246]
[246 246 246]
[246 246 246]]]
[[246 246 246 ... 246 246 246]
[246 246 246 ... 246 246 246]
[246 246 246 ... 246 246 246]
...
[246 246 246 ... 246 246 246]
[246 246 246 ... 246 246 246]
[246 246 246 ... 246 246 246]]
Conclusion
收獲:除了深入了解imread函數的參數,更多的是知道3 channels colored img可以直接讀取為1 channel grayscale img;而1 channel grayscale img也可以讀取為3 channels colored img。