????????在計算機視覺領域,Python的cv2庫是一個不可或缺的工具,它提供了豐富的圖像處理功能。作為OpenCV的Python接口,cv2使得圖像處理的實現變得簡單而高效。
?示例圖片
目錄
opencv獲取方式
圖像基本知識
顏色空間
RGB
HSV
圖像格式
BMP格式
? TIFF格式
GIF格式
JPEG格式
PNG格式
讀取圖像cv2.imread()
? imread各flags參數含義詳解
讀取結果說明
Ndarray說明
獲取單通道顏色矩陣
顯示圖像
使用cv2.imshow()顯示圖像
cv2.waitKey()
cv2.destroyAllWindows()
使用plt.imshow()顯示圖像
保存圖像cv2.imwrite()
總結
?opencv獲取方式
pip install -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple opencv-python
圖像基本知識
顏色空間
????????顏色空間是一種用來表示顏色的數學模型,它描述了如何將顏色信息數字化,以便于計算機進行處理和分析。在計算機視覺和圖像處理領域,常見的顏色空間包括RGB、HSV等。
RGB
????????RGB顏色空間是最常用的顏色空間之一,它基于紅(Red)、綠(Green)、藍(Blue)三種基本顏色,通過調整這三種顏色的強度和組合,可以產生各種顏色。
????????在RGB顏色空間中,每個顏色的強度值范圍通常在0到255之間,分別代表紅、綠、藍三種顏色的亮度。通過調整這些亮度值,可以混合出各種顏色。例如,當RGB三個通道的強度值都為0時,表示黑色;當RGB三個通道的強度值都為255時,表示白色。
RGB顏色調色板?
????????HEX是一種常用于網頁設計和圖像處理中的顏色表示方法,它通過六位十六進制數來表示RGB顏色空間中的顏色。在HEX表示法中,前兩位代表紅色強度,中間兩位代表綠色強度,最后兩位代表藍色強度。?
????????通過改變這三個值的不同組合,可以得到一個包含2^24=16777216種顏色的調色板,但是人眼可見的卻遠遠少于這個數字。
????????例如我們總是認為烏鴉是黑色的,但其實在不同的光照條件下,烏鴉的羽毛可能會呈現出彩色的光澤。這正是因為RGB顏色空間雖然能夠表示大量的顏色,但人眼的顏色感知卻受到環境、光照等多種因素的影響。
?烏鴉羽毛五彩斑斕的黑
HSV
????????HSV(Hue, Saturation, Value)是根據顏色的直觀特性 色調(Hue)、飽和度(Saturation)和明度(Value)三個參數。由A. R. Smith在1978年創建的一種顏色空間, 也稱六角錐體模型(Hexcone Model)。
?HSV分量可以通過RGB各分量值轉化得到,計算公式如下:
其中,R,G,B分別為RGB顏色空間中的3個分量。?
圖像格式
常見的圖像格式有BMP格式,TiIFF格式,GIF格式,JPEG格式,PNG格式等。
BMP格式
????????BMP格式是windows環境中的一種標準(但很多Microsoft應用程序不支持它),這種格式采用位映射存儲格式,除了圖像深度可選以外,不采用其他任何壓縮,因此,BMP文件所占用的空間很大。BMP文件的圖像深度可選lbit、4bit、8bit及24bit。BMP文件存儲數據時,圖像的掃描方式是按從左到右、從下到上的順序。由于BMP文件格式是Windows環境中交換與圖有關的數據的一種標準,因此在Windows環境中運行的圖形圖像軟件都支持BMP圖像格式。
? TIFF格式
????????TIFF格式是一種靈活的圖像存儲格式,廣泛應用于印刷、出版和掃描領域。它支持多種色彩模式,包括灰度、RGB、CMYK等,并允許無損壓縮,以在保證圖像質量的同時減少文件大小。TIFF格式還支持多層圖像和透明度,使其在處理復雜圖像時具有顯著優勢。此外,TIFF格式具有良好的兼容性,能夠被多種圖像編輯和處理軟件所支持。
GIF格式
????????GIF格式是一種廣泛用于網絡傳輸的圖像格式。GIF格式以其獨特的無損壓縮技術和支持透明背景的特性而著稱,這使得GIF圖像在保持高質量的同時,文件大小相對較小,非常適合在網絡上快速加載和顯示。此外,GIF格式還支持動畫效果,能夠創建簡單的動態圖像,這一特性使其在社交媒體和網頁設計中備受歡迎。盡管GIF格式的色彩深度有限,通常只能顯示256種顏色,但這并不妨礙它在特定應用場景下的廣泛應用。
JPEG格式
????????JPEG格式源自對相對靜止灰度或彩色圖像的一種壓縮標準,在使用有損壓縮方法時可節省的空間是相當大的,目前數碼相機中均使用這種格式。盡管JPEG格式采用有損壓縮,可能會導致一定的圖像質量損失,但通過調整壓縮級別,用戶可以在圖像質量和文件大小之間找到理想的平衡點。這種靈活性使得JPEG格式成為存儲和傳輸大量圖片的優選方案,尤其是在存儲空間有限或網絡帶寬受限的情況下。此外,JPEG格式還具有良好的跨平臺兼容性,幾乎可以被所有主流的圖像查看器和編輯器所支持。
PNG格式
????????PNG是一種無損壓縮的圖像格式,支持透明背景和Alpha通道,使得圖像在保持高質量的同時,還能展現出更為豐富的層次感和細膩度。與GIF格式相比,PNG格式在色彩深度上不再受限,能夠顯示1600多萬種顏色,這為圖像的色彩表現提供了更廣闊的空間。此外,PNG格式還支持多種圖像編輯功能,如伽瑪校正、文本注釋等,進一步增強了其在圖像處理和編輯領域的實用性。由于其無損壓縮的特性,PNG格式在需要保持圖像原始質量和細節的應用場景中,如網頁設計中的圖標、按鈕等,具有不可替代的優勢。
需要注意的是PNG格式的圖片相對于其他格式圖片來說,除了RGB三通道以外還多了一層alpha通道,這一層alpha通道使得PNG圖片支持透明度設置,即可以實現圖片的半透明效果,或者是摳圖后的圖片背景透明化。
讀取圖像cv2.imread()
#cv2.imread讀取圖像
import cv2
image=cv2.imread(filename='test.jpg',flags=cv2.IMREAD_UNCHANGED)
#filename:圖像文件的路徑
#flags:#cv2.IMREAD_COLOR:BGR格式彩色圖像 #cv2.IMREAD_GRAYSCALE:灰度圖像,是單通道的 #cv2.IMREAD_UNCHANGED:包括alpha通道,即透明通道#cv2.IMREAD_COLOR_BGR,以BGR格式讀取圖像,彩色#cv2.IMREAD_COLOR_RGB,以RGB格式讀取圖像,彩色#cv2.IMREAD_ANYDEPTH:讀取任意深度的圖像#cv2.IMREAD_ANYCOLOR:讀取任意顏色的圖像#cv2.IMREAD_LOAD_GDAL:使用GDAL讀取圖像#cv2.IMREAD_REDUCED_COLOR_2:讀取1/2的彩色圖像#cv2.IMREAD_REDUCED_COLOR_4:讀取1/4的彩色圖像#cv2.IMREAD_REDUCED_COLOR_8:讀取1/8的彩色圖像#cv2.IMREAD_REDUCED_GRAYSCALE_2:讀取1/2的灰度圖像#cv2.IMREAD_REDUCED_GRAYSCALE_4:讀取1/4的灰度圖像#cv2.IMREAD_REDUCED_GRAYSCALE_8:讀取1/8的灰度圖像#cv2.IMREAD_IGNORE_ORIENTATION:忽略圖像的方向信息#cv2.IMREAD_COLOR是默認值,讀取的圖像是彩色BGR格式相當與cv2.IMREAD_COLOR_BGR
print(image.shape)
? cv2.imread()函數各flags參數含義詳解
? ? ? ? ????????cv2.imread()函數只有兩個參數,filename與flages,filename指圖像文件路徑,flags是指定圖像讀取的方式。
以下是所有flags釋義:
? ? ? ? ?
cv2.IMREAD_COLOR | 讀取彩色圖像 |
cv2.IMREAD_GRAYSCALE | 讀取單通道的灰度圖像 |
cv2.IMREAD_UNCHANGED: | 按照圖像原格式讀取圖像,若圖像是png圖像那么包括alpha通道,即透明通道,此時圖像是四通道的,若圖像不是png格式那么還是三通道。 |
?cv2.IMREAD_COLOR_BGR | 以BGR格式讀取圖像,彩色 |
?cv2.IMREAD_COLOR_RGB | 以RGB格式讀取圖像,彩色 |
cv2.IMREAD_ANYDEPTH | 讀取任意深度的圖像 |
?cv2.IMREAD_ANYCOLOR | 讀取圖像時自動檢測并保留圖像的原始顏色通道數。 |
cv2.IMREAD_LOAD_GDAL | 使用GDAL讀取圖像。GDAL 是專門用于處理地理空間數據格式的庫,如 GeoTIFF、ENVI、HFA 等。 |
cv2.IMREAD_REDUCED_COLOR_2 | 讀取1/2的彩色圖像 |
cv2.IMREAD_REDUCED_COLOR_4 | 讀取1/4的彩色圖像 |
?cv2.IMREAD_REDUCED_COLOR_8: | 讀取1/8的彩色圖像 |
cv2.IMREAD_REDUCED_GRAYSCALE_2 | 讀取1/2的灰度圖像 |
cv2.IMREAD_REDUCED_GRAYSCALE_4 | 讀取1/4的灰度圖像 |
cv2.IMREAD_REDUCED_GRAYSCALE_8 | 讀取1/8的灰度圖像 |
cv2.IMREAD_IGNORE_ORIENTATION | 忽略圖像的方向信息 |
讀取結果說明
Ndarray說明
? ? ? ? ? Ndarray的一般結構為:
[行數,列數,深度]
????????其中行和列都是一維數組,我們知道行*列便可以構成矩陣,而深度則用來表示不同的行*列構成的矩陣的在最外層的數組中的索引。簡而言之,Ndarray就是數組內嵌套矩陣的格式,這樣會十分方便理解。
????????? 上述代碼中的image為讀取結果,由于我們的示例圖片是.jpg格式沒有alpha通道,所以flags使用cv2.IMREAD_UNCHANGED與cv2.IMREAD_COLOR并沒有區別,通道數都為3。
?image的shape:(1161, 1080, 3)
? ? ? ? cv2.imread()函數的結果是ndarray,我們打印出其shape的結果中前兩個參數是圖像的高與寬,第三個參數是image的維度,這里的維度其實就是圖像的RGB通道數。
獲取單通道顏色矩陣
????????倘若我們想要分別切片獲取image的三個通道數對應的顏色矩陣,那么我們可以這樣寫:
blue=image[:,:,0]
green=image[:,:,1]
red=image[:,:,2]
#或者
blue=image[0:1161,0:1080,0]
green=image[0:1161,0:1080,1]
red=image[0:1161,0:1080,2]
? ? ? ? ? ?在第一種寫法中,這里要說明一下的是,Ndarray的切片方法與python的list切片方法一致,切片時有一個特殊用法就是[:],它相當與[0:len(array)]用來直接獲取整個數組所有值,倘若你要是不知道某一維這個數組的長度(比如上邊我們讀取的圖像高1161寬1080,直接切片需[0:1161,0:1080]),又想獲取整個數組的所有內容,可以使用這種方法。
????????當然,為了方便,cv2已經內置了split函數替我們直接獲取三個顏色通道的矩陣。
blue,green,red=cv2.split(image)
顯示圖像
使用cv2.imshow()顯示圖像
import cv2#opencv讀取的格式是BGR
image=cv2.imread('test.jpg')
image=cv2.resize(image,(500,500))#更改一下圖像大小,為了方便顯示
cv2.imshow('image',image)
cv2.waitKey(0)
cv2.destroyAllWindows()
????????這里的image是一個shape為(500,500,3)的ndarray,表示這是一個500x500像素的彩色圖像,具有紅、綠、藍三個顏色通道。每個顏色通道都是一個500x500的二維數組。
結果
cv2.waitKey()
????????cv2.waitKey()函數是用來在OpenCV庫中暫停程序執行并等待用戶按鍵的函數。這個函數通常在顯示圖像時使用,比如在一個窗口中顯示圖像后,我們希望程序在用戶按下任意鍵后再繼續執行后續操作,這時就可以使用cv2.waitKey()函數。該函數接受一個整數參數,表示等待的毫秒數。如果參數為0,則表示無限期等待,直到用戶按下鍵盤上的任意鍵。在按下鍵后,cv2.waitKey()會返回按鍵的ASCII碼值,我們可以根據這個返回值來判斷用戶按下了哪個鍵。
????????需要注意的是,在使用cv2.waitKey()之前,必須已經創建了一個圖像顯示窗口,否則該函數將無法正常工作。
? ? ? ? 同時,倘若你使用cv2.imshow()想要顯示image,但是卻沒有在代碼中加入這一行cv2.waitKey(0)命令,那么圖片將不會正常顯示,顯示結果為黑色背景。
cv2.destroyAllWindows()
? ? ??cv2.destroywindows()函數是用來關閉所有OpenCV創建過的窗口的,這些窗口實際是都是使用python內置庫tkinter編寫的,先前的tkinter窗口會阻塞主線程。所以,當我們完成圖像處理或顯示操作后,經常需要關閉這些窗口以釋放資源。倘若不將他們關閉當前圖像窗口可能無法顯示。
cv2.namedWindow()
????????cv2.namesWindow()函數寫在cv2.imshow()函數之前,它主要用來設置cv2.imshow()函數彈出的窗口的屬性。
比如:我們正常使用cv2.imshow()顯示的圖像的窗口不可拉伸,我們只需要在cv2.imshow()函數之前,加一行以下代碼便可實現窗口可拉伸:
#cv2.namedWindow()函數調整圖像顯示窗口'''
cv2.namedWindow()所有flags:
cv2.WINDOW_AUTOSIZE
cv2.WINDOW_FREERATIO
cv2.WINDOW_FULLSCREEN
cv2.WINDOW_GUI_EXPANDED
cv2.WINDOW_GUI_NORMAL
cv2.WINDOW_KEEPRATIO
cv2.WINDOW_NORMAL
cv2.WINDOW_OPENGL'
'''
import cv2#opencv讀取的格式是BGR
image=cv2.imread('test.jpg')
image=cv2.resize(image,(500,500))
cv2.namedWindow('image',cv2.WINDOW_GUI_NORMAL)
cv2.imshow('image',image)
cv2.waitKey(0)
cv2.destroyAllWindows()
圖像所在窗口可以x,y方向拉伸?
cv2.namedWindow()函數只有兩個參數,winname與flags,winname是待作用的窗口名稱,flags用來設置該窗口的屬性,以下是cv2.namedWindow()函數所有flags及其含義:
cv2.WINDOW_AUTOSIZE | 窗口大小會自動調整為與輸入圖像的大小相同,用戶無法手動調整窗口尺寸 。創建窗口后,圖像以原始大小顯示在窗口中,窗口大小隨圖像尺寸變化而自適應 |
cv2.WINDOW_FREERATIO | 窗口中的圖像可以自由縮放,不保持圖像的原始寬高比。這意味著在調整窗口大小時,圖像會按照窗口的變化隨意拉伸或壓縮,可能會導致圖像變形? |
cv2.WINDOW_FULLSCREEN | 創建一個全屏窗口,窗口將占據整個屏幕,通常需要通過特定的系統操作(如按下特定快捷鍵)來退出全屏模式 。通過waitkey()函數實現 |
cv2.WINDOW_GUI_EXPANDED | 提供擴展的GUI功能,允許更豐富的用戶界面元素和交互方式。這個標志通常用于創建具有更多控件和功能的窗口,不過具體的表現和可用功能可能依賴于OpenCV的版本和底層使用的GUI后端? |
cv2.WINDOW_GUI_NORMAL | 創建具有標準GUI外觀和功能的窗口,這是最常見的窗口創建模式,提供基本的窗口操作(如關閉按鈕等),沒有額外的擴展功能? |
cv2.WINDOW_KEEPRATIO | 窗口中的圖像在縮放時會保持其原始的寬高比。當調整窗口大小時,圖像會根據窗口的變化按比例縮放,以確保圖像不會變形? |
cv2.WINDOW_NORMAL | 允許用戶手動調整窗口的大小與?cv2.WINDOW_AUTOSIZE ?不同,此模式下窗口大小不會自動適應圖像大小,用戶可以根據需要改變窗口尺寸,圖像也會相應地進行縮放顯示? |
cv2.WINDOW_OPENGL | 創建支持OpenGL的窗口,這使得可以在窗口中使用OpenGL的圖形渲染功能,適用于需要高級圖形處理和交互的應用場景? |
使用plt.imshow()顯示圖像
import cv2#opencv讀取的格式是BGR
import matplotlib.pyplot as plt#matplotlib讀取的格式是RGB
image=cv2.imread('test.jpg')
image=cv2.resize(image,(500,500))
#使用plt.imshow(),需要先將BGR轉化成RGB,這里使用cv2.cvtColor顏色通道轉換函數完成
image=cv2.cvtColor(image,cv2.COLOR_RGB2BGR)
plt.axis('off')
plt.imshow(image)
結果
????????這里需要注意的是opencv讀取的圖像時默認格式是BGR,而matplotlib讀取的格式是RGB,如果我們在讀取圖像時不指定讀取方式且不使用cv2.cvtColor()通道轉換函數將顏色通道轉換成RGB的話,那么顯示出來的圖像的顏色便會怪怪的。。。
????????這是因為,matplotlib把原本是紅色的通道誤認為是藍色通道,而原本是藍色的通道則被認為是紅色通道。這種顏色通道的錯位就會導致圖像顏色顯示異常、
????????但是,無論如何,cv2.imshow與plt.imshow這兩個函數在顯示圖像時,需要傳入的都是圖像的ndarray數據。
保存圖像cv2.imwrite()
#cv2.imwrite保存圖像
import cv2
image=cv2.imread(filename='test.jpg',flags=cv2.IMREAD_UNCHANGED)
#圖像經過某些變換或操作后需要保存
cv2.imwrite(filename='newImage.jpg',img=image,params=[int(cv2.IMWRITE_JPEG_QUALITY), 50])
#filename:保存圖像文件名稱
#img:圖像顏色矩陣
#params:參數是一個可選的序列(通常是列表或元組),用于傳遞圖像編碼和壓縮相關的參數。
????????當我們需要保存圖像時,直接調用cv2.imwrite()函數即可。?
總結
????????本文主要介紹了opencv圖像的讀取與顯示,后序還將分享更多相關圖像處理技術,以及如何利用cv2進行圖像特征提取和匹配。并且還會將所有內容合并到專欄中,免費訂閱。
????????通過本專欄的學習,讀者將能夠利用cv2庫解決實際的圖像處理問題,為計算機視覺項目打下堅實基礎。