6個案例手把手教你用Python和OpenCV進行圖像處理
01 圖像的讀取、顯示和保存
OpenCV提供了cv2模塊,用于進行圖像的處理操作。
1. 讀取圖像
OpenCV提供了cv2.imread()函數用于進行圖像的讀取操作。該函數的基本格式為:
- retval = cv2.imread(filename[, flags])
其中:
- retval是返回值,其值是讀取到的圖像。
- filename是要讀取圖像的完整文件名。
- flags是讀取標記,用來控制讀取文件的類型。部分常用的標記值如表3-1所示,其中第一列的值與第三列的數值表示的含義一致。
▲表3-1 常用flags標記值
- 例3-1 使用cv2.imread()函數讀取一幅圖像
代碼如下:
- import cv2 as cv
- image = cv2.imread("F:/picture/lena.png") # 讀取lena圖像
- print(image)
運行代碼會得到lena圖像的像素值,如圖3-3所示。
▲圖3-3 lena圖像部分像素值
2. 顯示圖像
OpenCV提供了多個與圖像顯示有關的函數,下面簡單介紹常用的幾個。
namedWindow()函數用來創建指定的窗口,一般格式如下:
- None = cv2.namedWindow(window)
其中,window是窗口的名字。例如:
- cv2.namedWindow("image")
這句程序會新建一個名字為image的窗口。
imshow()函數用來顯示圖像,其一般格式如下:
- None = cv2.imshow(window, image)
其中:
- window是窗口的名字。
- image是要顯示的圖像。
waitKey()函數用來等待按鍵,當有鍵被按下時,該語句會被執行。其一般格式如下:
- retval= cv2.waitKey([delay])
其中:
- retval是返回值。
- delay表示等待鍵盤觸發的時間,單位是ms。當該值為負數或0時表示無限等待,默認值為0。
destroyAllWindows函數用來釋放所有窗口,其一般格式為:
- None = cv2. destroyAllWindows ()
- 例3-2 顯示讀取的圖像
代碼如下:
- import cv2 as cv # 導入從cv2模塊
- image = cv.imread("F:/picture/lena.png") # 讀取lena圖像
- cv.namedWindow("image") # 創建一個image的窗口
- cv.imshow("image", image) # 顯示圖像
- cv.waitKey() # 默認為0,無限等待
- cv.destroyAllWindows() # 釋放所有窗口
程序運行結果如圖3-4所示。
▲圖3-4 例3-2的運行結果
3. 保存圖像
OpenCV中提供了cv2.imwrite()函數來保存圖像,其一般格式為:
- retval= cv2.imwrite(filename, img[, params])
其中:
- retval是返回值。
- filename是要保存的圖像的完整路徑名,包括文件的擴展名。
- img是要保存的圖像的名字。
- params是保存的類型參數,可選。
- 例3-3 編寫程序,將讀取到的圖像保存
代碼如下:
- import cv2 as cv # 導入從cv2模塊
- image = cv.imread("F:/picture/lena.png") # 讀取lena圖像
- cv.imwrite("F:/picture/lenaresult.png",image) #將圖像保存到F:/picture/下,名字為lenaresult
02 圖像通道的基本操作
在圖像處理過程中,有時會根據需要對通道進行拆分與合并。在OpenCV中提供了split()和merge()函數對圖像進行拆分與合并。下面對這兩個函數進行介紹。
1. split()拆分函數
函數split()可以拆分圖像的通道,例如BGR圖像的三個通道。其一般格式如下:
- b,g,r = cv2.split(img)
其中:
- b、g、r分別是B通道、G通道、R通道的圖像信息。
- img是要拆分的圖像。
- 例3-4 編寫程序,使用split()函數對圖像進行拆分
代碼如下:
- import cv2 as cv
- image = cv.imread("F:/picture/lena.png")
- b,g,r = cv.split(image) # 拆分圖像通道分為b,g,r三個通道
- cv.imshow("b",b) # 顯示b通道的圖像信息
- cv.imshow("g",g) # 顯示g通道的圖像信息
- cv.imshow("r",r) # 顯示r通道的圖像信息
- cv.imshow("image", image)
- cv.waitKey()
- cv.destroyAllWindows()
程序運行結果如圖3-5所示。
▲圖3-5 例3-4的運行結果:a)原始圖像,b)B通道圖像,c)G通道圖像,d)R通道圖像
其中,圖3-5a是原圖,圖3-5b是B通道的圖像,圖3-5c是G通道的圖像,圖3-5d是R通道的圖像。
2. merge()合并函數
通道合并是通道拆分的逆過程,可以將三個通道的灰度圖像合并為一張彩色圖像。OpenCV中提供了merge()函數來實現圖像通道的合并,其基本格式為:
- imagebgr = cv2.merge([b,g,r])
其中:
- imagebgr是合并后的圖像。
- b、g、r分別是B通道、G通道、R通道的圖像信息。
- 例3-5 編寫程序,演示合并圖像的過程
代碼如下:
- import cv2 as cv
- image = cv.imread("F:/picture/lena.png")
- b,g,r = cv.split(image) # 拆分圖像通道分為b,g,r三個通道
- imagebgr = cv.merge([b,g,r]) # 將b,g,r三個通道的圖像合并
- cv.imshow("image", image)
- cv.imshow("imagegbgr", imagebgr)
- cv.waitKey()
- cv.destroyAllWindows()
程序運行結果如圖3-6所示。
▲圖3-6 例3-5的運行結果:a)原始圖像 b)拆分并合并后的圖像
其中,圖3-6a是原始圖像,圖3-6b是經過拆分后又合并的圖像。
03 圖像屬性的獲取
在進行圖像處理時經常需要獲取圖像的大小、類型等屬性信息。下面介紹幾個常用屬性。
- shape:表示圖像的大小。如果是彩色圖像,則返回包含行數、列數和通道數的數組;如果是二值圖像或灰度圖像,則返回包含行數和列數的數組。
- size:表示返回的圖像的像素數目。
- dtype:表示返回的圖像的數據類型。
- 例3-6 編寫程序,觀察圖像的屬性值
代碼如下:
- import cv2 as cv
- image = cv.imread("F:/picture/lena.png")
- print("image.shape",image.shape) # 輸出圖像的大小屬性
- print("image.size",image.size) # 輸出圖像的像素數目屬性
- print("image.dtype",image.dtype) # 輸出圖像的類型屬性
程序運行結果為:
- image.shape (512, 512, 3)
- image.size 786432
- image.dtype uint8
關于作者:高敬鵬,博士學歷,碩士生導師,2002年至今,任職于哈爾濱工程大學信息與通信工程學院。研究方向主要包括人工智能、機器學習、圖像處理、信號檢測、目標識別、現代通信技術與電子系統等。
江志燁,博士學歷,研究員,任職于北京航天長征飛行器研究所。
趙娜,博士學歷,講師,任職于重慶電子工程職業學院。
本文摘編自《機器學習:基于OpenCV和Python的智能圖像處理》,經出版方授權發布。