一、學習目標
- 了解圖片的通道與數組結構
- 了解使用numpy創建一個圖片
- 了解使用numpy對圖片的一般操作方法
目錄
[python opencv 計算機視覺零基礎到實戰] 一、opencv的helloworld
[【python opencv 計算機視覺零基礎到實戰】二、 opencv文件格式與攝像頭讀取] 一、opencv的helloworld
[[python opencv 計算機視覺零基礎到實戰] 三、numpy與圖像編輯] 一、opencv的helloworld
[[python opencv 計算機視覺零基礎到實戰] 四、了解色彩空間及其詳解] 一、opencv的helloworld
[[python opencv 計算機視覺零基礎到實戰] 五、對象追蹤] 一、opencv的helloworld
如有錯誤歡迎指出~
二、了解numpy對圖像的編輯
2.1 了解zeros方法的使用方法并且輸入了解uint8類型
在前兩節中,我們對圖像的屬性進行了查看,得到了寬、高以及通道,但是我們對整體的圖片數據結構還是存在一定的不理解;這一節將加深對圖片數據結構上的理解,方便我們接下來的學習。
首先我們需要使用numpy創建一張圖片,從最基本的操作逐步對圖像數據結構進行了解。我們先在代碼頭部引入所需庫:
import cv2
import numpy as np
引入之后,我們可以使用numpy創建一個指定大小以及通道數的圖片數據;可以使用numpy的zeros方法。zeros方法可以把數組轉換為我們所需要的矩陣,并且這個數組將會以0這個元素進行填充。zeros接收3個參數,第一個參數為shape形狀,這個形狀指你這個數組需要的維度;第二個接收的參數為dtype,表示該數組的數據類型,默認為numpy.float64;第三個接收的參數為order,這個參數是可選參數,有2個默認選項,分別是C與F,表示是行優先還是列優先,由于我們現在用不到所以暫時不做過多講解。
搞明白了zeros方法的參數后,我們可以簡單的創建一個一位數組:
data=np.zeros(3)
print(data)
以上代碼是創建了有3個元素的一維數組,用0進行填充,并且將值進行輸出,結果如下:
那如何創建一個二維數組呢?很簡單,但很多人會寫錯,以下是個錯誤示例:
data=np.zeros(3,2)
以上使用逗號進行間隔后,2作為了第二個參數dtype,但是dtype中并沒有該類型,所以導致了錯誤,將會提示:
這是進行傳參應該使用方括號或者圓括號將參數進行說明,代碼如下:
data=np.zeros([3,2])
或
data=np.zeros((3,2))
運行結果如下:
我們已知第二個參數dtype,接下來我們嘗試一下使用uint8類型對創建進行指定:
data=np.zeros((3,2),np.uint8)
print(data)
得到結果為:
由于在第一節中,我們已了解uint8的數據范圍就是0-255,我們將創建的3行2列的數組第0列第0個做加法運算,增加258,查看是否將會數據溢出:
data=np.zeros((3,2),np.uint8)
data[0][1]=data[0][1]+258
print(data[0][1])
運行結果如下:
結果正確,數據并沒有超過258,通過這個示例我們更加的了解了uint8該類型的取值范圍。
2.2 了解使用numpy創建與圖片數據結構一致的數據類型
我們已知一張圖片的數據類型為uint8,并且是3通道的,那么我們這時將可以通過zeros創建一張與圖片數據結構類似的圖片。現在我們創建一張長寬都為3,通道為3的數組矩陣:
data=np.zeros((3,3,3),np.uint8)
print(data)
這個查看數據:
以上結構很方便我們了解整個結構,接下來修改數據創建一個200*200,有3個通道的矩陣:
data=np.zeros((200,200,3),np.uint8)
創建完畢后我們可以使用顯示我們創建的一張“圖片”,并且需要添加等待,不然整個程序將會一閃而過:
data=np.zeros((200,200,3),np.uint8)
cv2.imshow("dataImg",data)
運行結果如下:
這個時候將會得到一張純黑色的圖片。我們現在可以通過搜索引擎查看對應純黑色的RGB值是多少,我通過搜索引擎查看,得到了0 0 0 為黑色;恰好,我們的數據都是以0作為填充的,所以結果為正確。查詢結果如下:
從以上圖片得知,顏色為白色則是255 255 255的RGB值,那么這時我們可以對該矩陣進行值的改變,即可得到一張白色圖片。那我們是否可以這樣編寫呢?
data=np.zeros((200,200,3),np.uint8)*255
以上的編寫方式是不對的,該方式是0成0,永遠等于0,不過以上方式可以使每個元素都乘上255。這個時候我們可以把數組的創建方法改為ones,ones與zeros類似,我們可以從方法名上可以得知,zeros是創建數組時填充0,那ones必定是填充1了。我們寫一個簡單代碼進行嘗試:
data=np.ones((3,3,3),np.uint8)
print(data)
運行結果如下:
修改之前的代碼將zeros方法改為ones方法,完整代碼如下:
import cv2
import numpy as npdata=np.ones((200,200,3),np.uint8)*255
cv2.imshow("dataImg",data)
cv2.waitKey (0)
cv2.destroyAllWindows()
這時將會得到一張白色的圖片:
2.3 使用OpenCV對圖片進行生成
其實我們在創建這些數據時,就已經是創建了一張圖片。我們的所有文件資源在計算機中都是以數字存儲,而我們所見的這些圖片只不過是以人類較為習慣的方式去進行呈現;即使我們操作Photoshop對圖片進行更改,那也是以一種人類較為習慣的方式去對一張圖片進行修改,但本質上是對數據的編輯。
那既然我們是創建了一張圖片,那我們就去保存這一張圖片。使用OpenCV的imwrite方法可以對圖片數據進行保存。imwrite接收兩個參數,第一個是path路徑,表示圖片存儲的位置,但是需要注意的是一定不能夠使用中文路徑,否則有可能會出現錯誤;第二個參數為一個數組類型的參數,也就是我們的圖像數據。那么我們就可以將自己生成的圖像數據傳入第二個參數。代碼如下:
import cv2
import numpy as npdata=np.ones((200,200,3),np.uint8)*255
cv2.imwrite(r"C:\Users\mx\Desktop\dataImg.png",data)
cv2.imshow("dataImg",data)
cv2.waitKey (0)
cv2.destroyAllWindows()
我所存儲的位置是桌面,運行程序后將會在桌面生成一個dataImg名稱的白色圖片。
我們以上代碼使用ones創建后,乘上255,這行代碼可以更改為:
data=np.zeros((200,200,3),np.uint8)
data.fill(255)
使用fill方法可以將一個數組內填充一個值。
2.4 了解通道到底指的是什么
有一些同學不了解圖像或者numpy,可能會對一些名稱有一定的不理解。什么是通道對于這一部分同學來說可能聽得還是有點糊涂的;很簡單,我們直接使用代碼來看通道是啥。
我們已經了解了numpy創建3個通道的圖片數據如下:
data=np.zeros((200,200,3),np.uint8)
那此時,我們將該代碼編程簡單直觀的方式,以便我們觀察,分別更改創建的數組為3,3與3,3,3以及3,3,4 :
data=np.zeros((3,3),np.uint8)
data=np.zeros((3,3,3),np.uint8)
這時候查看數據:
其實從3,3到3,3,3明顯的注意到是厚度增加了;我們之前說過,圖像是由3張單通道圖像組成,每一張表示一種色彩,其實就可以理解為我們所看見的圖像是由3張通道圖像疊加而成,這時就理解了該通道的含義。
注:文章首發于ebaina
三、總結
- 了解圖片的通道與數組結構
- 了解使用numpy使用zeros,ones創建圖像結構的數據
- 了解使用numpy使用fill對數據進行填充
- 了解了使用OpenCV 的imwrite方法保存數據