- 一些理解:
圖像信息在計算機中其實是作爲一個array存在的。
對於灰度圖,每個像素的值可以用一個uint8型表示(0->255,黑->白)。這樣整個灰度圖的圖片可以用一個二維數組表示。
例如,對於200x300(200,300指像素,一共有60000個像素)大小的灰度圖,可以用一個uint8 array[200, 300]表示。
對於彩色圖片,每個像素的位置還是用一個二位數組表示,而該位置處的像素值可以用一個size等於3的向量表示(例如3通道RGB圖)。整個圖片可以用一個width * height * number_of_channel表示(例如200*300*3)。有些圖片格式還有透明度信息,此時每個像素值將有4個channel。
對於R, G, B三個channel,每個channel可以用一個uint8表示,在R這個channel上,其值0->255表示黑色->紅色(前提是另外兩個channel你都設爲了0)。
寫個代碼練一練:
- 生成原始的圖像數據:
img = np.zeros(shape = (300, 400), dtype = np.uint8)
img包含了一些屬性:
print(img.shape) #output 300x400
print(img.size)
print(img.dtype)
print(img
運行結果:
(300, 400)
120000
uint8
[[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
...
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]
[0 0 0 ... 0 0 0]]
- 保存原始圖像數據到指定圖片格式:
cv2.imwrite("/home/kyle/Pictures/gray_img.jpg", img)
注意:在imwrite中,路徑參數不能用~/Pictures/***.jpg,我也不知爲什麼,如果這樣用的話程序運行不會報錯,但是在那個路徑下找不到保存的圖片文件。
然後就可以用圖片查看工具打開gray_img.jpg了。打開後你會發現是個全黑的圖片,因爲每個像素的值都是0。
- 圖片類型轉換:
例如將上一步生成的單通道的灰度圖轉換爲3通道的BGR圖:
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
print(img.shape) #output 300x400x3, 3 channel.
print(img.size)
print(img.dtype)
print(img
打印輸出:
(300, 400, 3)
360000
uint8
[[[0 0 0]
[0 0 0]
[0 0 0]
...
[0 0 0]
[0 0 0]
[0 0 0]]]
- 修改圖片指定像素的值
#img[:, :] = 200 #change the value of all channels to 200.
img[:, :, 1] = 200 #change the value of channel 1 to 200.
print(img)
- 顯示圖片:
如果需要手動調整顯示圖片的窗口,需要cv2.namedWindow("Image",cv2.WINDOW_NORMAL)
如果需要窗口自適應圖片大小,需要cv2.namedWindow("Image",cv2.WINDOW_AUTOSIZE)
默認是窗口自適應。
cv2.namedWindow("Image")
cv2.imshow("Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
- 讀取圖片:
默認情況下,即使圖像文件爲灰度格式,imread()函數也會返回BGR格式的圖像。該函數包含一些可配置的參數:
IMREAD_GRAYSCALE = 0
IMREAD_COLOR = 1
IMREAD_ANYDEPTH = 2
IMREAD_ANYCOLOR = 4
IMREAD_LOAD_GDAL = 8
IMREAD_UNCHANGED = -1
例如,將一幅彩色圖片以灰度圖的方式讀取,並以灰度圖的方式保存到本地:
grayImage = cv2.imread("/home/kyle/Pictures/test.jpg", cv2.IMREAD_GRAYSCALE)
cv2.imwrite("/home/kyle/Pictures/test_gray.png", grayImage)
原圖與另存後的圖:
你也可以嘗試其他參數,查看讀取的結果。
完整代碼:
GitHub地址:GitHub
#!/usr/bin/env python3
import numpy as np
from cv2 import cv2 #if you use "import cv2", it will occurs some error prompt in vscode.
def test():
img = np.zeros(shape = (300, 400), dtype = np.uint8)
print(img.shape) #output 300x400
print(img.size)
print(img.dtype)
print(img)
#save img to file. I don't know why can't use "~/Pictures/gray_img.jpg".
cv2.imwrite("/home/kyle/Pictures/gray_img.jpg", img)
img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
print(img.shape) #output 300x400x3, 3 channel.
print(img.size)
print(img.dtype)
print(img)
#img[:, :] = 200 #change the value of all channels to 200.
img[:, :, 1] = 200 #change the value of channel 1 to 200.
cv2.imwrite("/home/kyle/Pictures/color_img.jpg", img)
print(img)
img[90:190, 30:120, 0] = 255
cv2.namedWindow("Image") #not necessary.
cv2.imshow("Image", img)
grayImage = cv2.imread("/home/kyle/Pictures/test.jpg", cv2.IMREAD_GRAYSCALE)
cv2.imwrite("/home/kyle/Pictures/test_gray.png", grayImage)
cv2.namedWindow("Image2")
cv2.imshow("Image2", grayImage)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == '__main__':
test()