宣告:由于 CSDN 發文助手 禁止使用 “小白”作為標題,修改為“大白”才能通過,但本文仍然面向小白同學,也歡迎“大白”批評指正,
本系列面向 Python 小白,從零開始實戰解說 OpenCV 專案實戰,
本節介紹影像的讀取、保存和顯示,除基本方法和例程外,還給出了從網路讀取影像、讀取/保存中文路徑影像、按指定大小顯示影像、組合顯示多個影像、通過 matplotlib 顯示彩色和灰度影像的例程,
1. 影像的讀取
函式 cv2.imread() 用于從指定的檔案讀取影像,
函式說明:
cv.imread(filename[, flags]) -> retval
- 函式 cv2.imread() 從指定檔案加載影像并回傳該影像的矩陣,
- 如果無法讀取影像(檔案丟失,權限不正確,格式不支持或無效),該函式回傳一個空矩陣,
- 目前支持的檔案格式:
- Windows 位圖 - * .bmp,* .dib
- JPEG 檔案 - * .jpeg,* .jpg,*.jpe
- JPEG 2000檔案 - * .jp2
- 便攜式網路圖形 - * .png
- WebP - * .webp
- 便攜式影像格式 - * .pbm,* .pgm,* .ppm * .pxm,* .pnm
- TIFF 檔案 - * .tiff,* .tif
引數說明:
- filename:要加載的檔案的路徑和名稱
- flags:讀取圖片的方式,可選項
- cv2.IMREAD_COLOR(1):始終將影像轉換為 3 通道BGR彩色影像,默認方式
- cv2.IMREAD_GRAYSCALE(0):始終將影像轉換為單通道灰度影像
- cv2.IMREAD_UNCHANGED(-1):按原樣回傳加載的影像(使用Alpha通道)
- cv2.IMREAD_ANYDEPTH(2):在輸入具有相應深度時回傳16位/ 32位影像,否則將其轉換為8位
- cv2.IMREAD_ANYCOLOR(4):以任何可能的顏色格式讀取影像
- 回傳值 retval:OpenCV 影像,nparray 多維陣列
注意事項:
- OpenCV 讀取影像檔案,回傳值是一個nparray 多維陣列,OpenCV 對影像的任何操作,本質上就是對 Numpy 多維陣列的運算,
- OpenCV 中彩色影像使用 BGR 格式,而 PIL、PyQt、matplotlib 等庫使用的是 RGB 格式,
- cv2.imread() 如果無法從指定檔案讀取影像,并不會報錯,而是數回傳一個空矩陣,
- cv2.imread() 指定圖片的存盤路徑和檔案名,在 python3 中不支持中文和空格(但并不會報錯),必須使用中文時,可以使用 cv2.imdecode() 處理,參見擴展例程,
- cv2.imread() 讀取影像時默認忽略透明通道,但可以使用 CV_LOAD_IMAGE_UNCHANGED 引數讀取透明通道,
- 對于彩色影像,可以使用 flags=0 按照讀取為灰度影像,
基本例程:
# 1.1 影像的讀取
imgFile = "../images/imgLena.tif" # 讀取檔案的路徑
img1 = cv2.imread(imgFile, flags=1) # flags=1 讀取彩色影像(BGR)
img2 = cv2.imread(imgFile, flags=0) # flags=0 讀取為灰度影像
擴展例程:
# 1.2 從網路讀取影像
import urllib.request as request
response = request.urlopen("https://profile.csdnimg.cn/8/E/F/0_youcans")
imgUrl = cv2.imdecode(np.array(bytearray(response.read()), dtype=np.uint8), -1)
# 1.3 讀取中文路徑的影像
imgFile = "../images/測驗圖01.png" # 帶有中文的檔案路徑和檔案名
# imread() 不支持中文路徑和檔案名,讀取失敗,但不會報錯!
# img = cv2.imread(imgFile, flags=1)
# 使用 imdecode 可以讀取帶有中文的檔案路徑和檔案名
img = cv2.imdecode(np.fromfile(imgFile, dtype=np.uint8), -1)
2. 影像的保存
函式 cv2.imwrite() 用于將影像保存到指定的檔案,
函式說明:
cv2.imwrite(filename, img [, flags])
- cv2.imwrite() 將 OpenCV 影像保存到指定的檔案,
- cv2.imwrite() 基于保存檔案的擴展名選擇保存影像的格式,
- cv2.imwrite() 只能保存 BGR 3通道影像,或 8 位單通道影像、或 PNG/JPEG/TIFF 16位無符號單通道影像,
引數說明:
- filename:要保存的檔案的路徑和名稱
- img:要保存的 OpenCV 影像,nparray 多維陣列
- flags:不同編碼格式的引數,可選項
- cv2.CV_IMWRITE_JPEG_QUALITY:設定 .jpeg/.jpg 格式的圖片質量,取值為 0-100(默認值 95),數值越大則圖片質量越高;
- cv2.CV_IMWRITE_WEBP_QUALITY:設定 .webp 格式的圖片質量,取值為 0-100;
- cv2.CV_IMWRITE_PNG_COMPRESSION:設定 .png 格式圖片的壓縮比,取值為 0-9(默認值 3),數值越大則壓縮比越大,
注意事項:
- cv2.imwrite() 保存的是 OpenCV 影像(多維陣列),不是 cv2.imread() 讀取的影像檔案,所保存的檔案格式是由 filename 的擴展名決定的,與讀取的影像檔案的格式無關,
- 對 4 通道 BGRA 影像,可以使用 Alpha 通道保存為 PNG 影像,
- cv2.imwrite() 指定圖片的存盤路徑和檔案名,在 python3 中不支持中文和空格(但并不會報錯),必須使用中文時,可以使用 cv2.imencode() 處理,參見擴展例程,
基本例程:
# 1.4 影像的保存
imgFile = "../images/logoCV.png" # 讀取檔案的路徑
img3 = cv2.imread(imgFile, flags=1) # flags=1 讀取彩色影像(BGR)
saveFile = "../images/imgSave.png" # 保存檔案的路徑
# cv2.imwrite(saveFile, img3, [int(cv2.IMWRITE_PNG_COMPRESSION), 8]) # 保存影像檔案, 設定壓縮比為 8
cv2.imwrite(saveFile, img3) # 保存影像檔案
擴展例程:
# 1.5 保存中文路徑的影像
imgFile = "../images/logoCV.png" # 讀取檔案的路徑
img3 = cv2.imread(imgFile, flags=1) # flags=1 讀取彩色影像(BGR)
saveFile = "../images/測驗圖02.jpg" # 帶有中文的保存檔案路徑
# cv2.imwrite(saveFile, img3) # imwrite 不支持中文路徑和檔案名,讀取失敗,但不會報錯!
img_write = cv2.imencode(".jpg", img3)[1].tofile(saveFile)
3. 影像的顯示
函式 cv2.imshow() 用于在視窗中顯示影像,
函式說明:
imshow(winname, img) -> None
- 函式 cv2.imshow() 在指定視窗中顯示 OpenCV 影像,視窗自適應影像大小,
- 顯示影像的縮放取決于影像深度:
- 對 8 位無符號影像,按原樣顯示;
- 對 16 位無符號或 32 位整數影像,將像素值范圍 [0,255 * 256] 映射到 [0,255] 顯示;
- 對 32 位浮點影像,將像素值范圍 [0,1] 映射到 [0,255] 顯示;
- 如果指定視窗尚未創建,則創建一個自適應影像大小的視窗;
- 如果要顯示大于螢屏解析度的影像,需要先呼叫 namedWindow("",WINDOW_NORMAL),
引數說明:
- winname:字串,顯示視窗的名稱,
- img:所顯示的 OpenCV 影像,nparray 多維陣列
注意事項:
- 函式 cv2.imshow() 之后要用 waitKey() 函式設定影像視窗的顯示時長,否則不會顯示影像視窗,
- 影像視窗將在 waitKey() 函式所設定的時長(毫秒)后自動關閉,waitKey(0) 表示視窗顯示時長為無限,
- 可以創建多個不同的顯示視窗,每個視窗必須命名不同的 filename,
- 可以用 destroyWindow() 函式關閉指定的顯示視窗,也可以用 destroyAllWindows() 函式關閉所有的顯示視窗,
基本例程:
# 1.6 影像的顯示(cv2.imshow)
imgFile = "../images/imgLena.tif" # 讀取檔案的路徑
img1 = cv2.imread(imgFile, flags=1) # flags=1 讀取彩色影像(BGR)
img2 = cv2.imread(imgFile, flags=0) # flags=0 讀取為灰度影像
cv2.imshow("Demo1", img1) # 在視窗 "Demo1" 顯示影像 img1
cv2.imshow("Demo2", img2) # 在視窗 "Demo2" 顯示影像 img2
key = cv2.waitKey(1000) # 等待按鍵命令, 1000ms 后自動關閉

擴展例程:
# 1.7 影像顯示(按指定大小的視窗顯示影像)
imgFile = "../images/imgLena.tif" # 讀取檔案的路徑
img1 = cv2.imread(imgFile, flags=1) # flags=1 讀取彩色影像(BGR)
cv2.namedWindow("Demo3", cv2.WINDOW_NORMAL)
cv2.resizeWindow("Demo3", 400, 300)
cv2.imshow("Demo3", img1) # 在視窗 "Demo3" 顯示影像 img1
key = cv2.waitKey(0) # 等待按鍵命令
# 1.8 影像顯示(多個影像組合顯示)
imgFile1 = "../images/imgLena.tif" # 讀取檔案的路徑
img1 = cv2.imread(imgFile1, flags=1) # flags=1 讀取彩色影像(BGR)
imgFile2 = "../images/imgGaia.tif" # 讀取檔案的路徑
img2 = cv2.imread(imgFile2, flags=1) # # flags=1 讀取彩色影像(BGR)
imgStack = np.hstack((img1, img2)) # 相同大小影像水平拼接
cv2.imshow("Demo4", imgStack) # 在視窗 "Demo4" 顯示影像 imgStack
key = cv2.waitKey(0) # 等待按鍵命令

4. 通過 matplotlib 庫顯示影像
函式 plt.imshow() 用于通過 matplotlib 庫顯示影像,
函式說明:
matplotlib.pyplot.imshow(img[, cmap])
OpenCV 使用 BGR 格式,matplotlib/PyQt 使用 RGB 格式,使用 matplotlib/PyQt 顯示 openCV 影像,要將 BGR 格式轉換為 RGB 格式:
# 圖片格式轉換:BGR(OpenCV) -> RGB(PyQt5)
imgRGB = cv2.cvtColor(imgBGR, cv2.COLOR_BGR2RGB)
引數說明:
- img:影像資料,nparray 多維陣列,對于 openCV(BGR)格式影像要先進行格式轉換
- cmap:顏色圖譜(colormap),默認為 RGB(A) 顏色空間
- gray:灰度顯示
- hsv:hsv 顏色空間
注意事項:
- OpenCV 和 matplotlib 中的彩色影像都是 Numpy 多維陣列,但 OpenCV 使用 BGR 格式,顏色分量按照藍/綠/紅的次序排列,而 matplotlib 使用 RGB 格式,顏色分量按照紅/綠/藍的次序排序,因此用 plt.imshow() 顯示 OpenCV 彩色影像時,先要進行顏色空間轉換,將Numpy 多維陣列按照紅/綠/藍的次序排序,
- plt.imshow() 可以直接顯示 OpenCV 灰度影像,不需要格式轉換,但需要使用 cmap=‘gray’ 進行引數設定,
- plt.imshow() 可以使用 matplotlib 庫中的各種方法繪圖,如標題、坐標軸、插值等,詳見 matploblib Document,
- PyQt5 也使用 RGB 格式,因此在 PyQt5 中顯示 OpenCV 彩色影像時,也要進行顏色空間轉換,
基本例程:
# 1.10 影像顯示(plt.imshow)
imgFile = "../images/imgLena.tif" # 讀取檔案的路徑
img1 = cv2.imread(imgFile, flags=1) # flags=1 讀取彩色影像(BGR)
imgRGB = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB) # 圖片格式轉換:BGR(OpenCV) -> RGB(PyQt5)
img2 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) # 圖片格式轉換:BGR(OpenCV) -> Gray
plt.rcParams['font.sans-serif'] = ['FangSong'] # 支持中文標簽
plt.subplot(221), plt.title("1. RGB 格式(mpl)"), plt.axis('off')
plt.imshow(imgRGB) # matplotlib 顯示彩色影像(RGB格式)
plt.subplot(222), plt.title("2. BGR 格式(OpenCV)"), plt.axis('off')
plt.imshow(img1) # matplotlib 顯示彩色影像(BGR格式)
plt.subplot(223), plt.title("3. 設定 Gray 引數"), plt.axis('off')
plt.imshow(img2, cmap='gray') # matplotlib 顯示灰度影像,設定 Gray 引數
plt.subplot(224), plt.title("4. 未設定 Gray 引數"), plt.axis('off')
plt.imshow(img2) # matplotlib 顯示灰度影像,未設定 Gray 引數
plt.show()
程式說明:
圖 1 中 OpenCV 的 BGR 彩色影像已轉換為 RGB 格式,彩色影像的顏色顯示正常;
圖 2 中 OpenCV 的 BGR 彩色影像格式未做轉換,彩色影像的顏色顯示例外;
圖 3 中 plt.imshow() 設定 cmap=‘gray’,灰度影像的顏色顯示正常;
圖 4 中 plt.imshow() 未設定 cmap=‘gray’,灰度影像的顏色顯示例外,

【本節完】
著作權宣告:
歡迎關注『Python 小白從零開始 OpenCV 學習課 @ youcans』 原創作品
原創作品,轉載必須標注原文鏈接:https://blog.csdn.net/youcans/article/details/121068773
Copyright 2021 youcans, XUPT
Crated:2021-11-01
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/347053.html
標籤:AI
