點贊 + 關注 + 收藏 = 學會了
前面介紹過在 OpenCV 裏可以通過 cv2.imread 讀取本地圖片,但這個方法無法讀取網絡圖片。
讀取網絡圖片:cv2.imdecode
在 OpenCV 裏讀取網絡圖片需要使用 cv2.imdecode 這個方法,它可以直接處理字節流(如網絡傳輸的圖像、攝像頭幀)而無需先保存為文件。
語法:
image = cv2.imdecode(buf, flags)
buf:必須是numpy.ndarray類型,通常通過np.frombuffer()將字節數據轉換而來。該 NumPy 數組的dtype(數據類型) 必須是np.uint8。這是因為圖像的編碼數據本質上是一串字節流,每個字節的值範圍是0到255,這恰好對應了8位無符號整數 (uint8) 的表示範圍 。flags:可選參數,指定解碼方式(與cv2.imread的flags相同)。是一個整數,它像一個指令開關,告訴imdecode函數我們希望以何種方式來解碼這張圖片 。這個參數決定了輸出圖像的顏色模式、是否保留透明通道等。
以下是幾個最常用、也最重要的 flags 值:
| 標誌常量 | 整數值 | 描述 |
|---|---|---|
cv2.IMREAD_COLOR |
1 | (默認值) 將圖像解碼為三通道的BGR彩色圖像。如果原始圖像有Alpha(透明)通道,它將被忽略並移除 。這是最常用的模式。 |
cv2.IMREAD_GRAYSCALE |
0 | 將圖像解碼為單通道的灰度圖像 。即使原始圖像是彩色的,也會被轉換為灰度圖。這在很多不需要顏色信息的場景(如邊緣檢測)中非常有用。 |
cv2.IMREAD_UNCHANGED |
-1 | 按原樣加載圖像。這是功能最全的模式,它會保留圖像的所有通道,包括Alpha(透明)通道 。如果你需要處理帶透明背景的PNG圖片,就必須使用這個標誌 。 |
cv2.IMREAD_ANYCOLOR |
4 | 以任意可能的顏色格式讀取圖像 。 |
舉個例子
# 導入OpenCV庫,用於圖像處理和顯示
import cv2
# 導入NumPy庫,用於數組操作
import numpy as np
# 導入SSL庫,用於處理HTTPS請求
import ssl
# 主程序入口,確保該代碼塊僅在直接運行腳本時執行
if __name__ == '__main__':
# 導入urllib.request模塊並簡化為request別名,用於網絡請求
import urllib.request as request
# 設置請求頭,模擬Chrome瀏覽器訪問,避免被服務器拒絕
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"}
# 創建請求對象,包含圖片URL和請求頭
req = request.Request("https://p9-passport.byteacctimg.com/img/user-avatar/6c49bd0b908f5b1601050a168d0283b2~60x60.awebp", headers=headers)
# 創建未經驗證的SSL上下文,解決HTTPS證書驗證問題
context = ssl._create_unverified_context()
# 發送請求並獲取響應,使用SSL上下文避免證書錯誤
response = request.urlopen(req, context=context)
# 讀取響應內容,轉換為字節數組,再轉為NumPy數組,最後解碼為OpenCV圖像
imgUrl = cv2.imdecode(np.array(bytearray(response.read()), dtype=np.uint8), -1)
# 創建窗口顯示圖片,窗口標題為"imgUrl"
cv2.imshow("imgUrl", imgUrl)
# 等待用户按鍵輸入,0表示無限等待
key = cv2.waitKey(0)
# 判斷用户是否按下'q'鍵
if key == ord("q"):
# 關閉所有OpenCV創建的窗口
cv2.destroyAllWindows()
在這個例子中,通過 request 發起請求,模擬了瀏覽器請求,獲取我在掘金的頭像圖片。
然後用 cv2.imdecode 方法加載我的頭像。
最後通過 cv2.waitKey(0) 讓圖片一直展示,直至按下 q 鍵才關閉圖片窗口。
為何需要 cv2.imread 和 cv2.imdecode 兩個API?
cv2.imread 和 cv2.imdecode似乎在做同樣的事情——將某種格式的數據變成OpenCV可以處理的圖像矩陣。那麼,為什麼需要兩個獨立的函數呢?這並非冗餘設計,而是體現了軟件工程中一個極其重要的原則:單一職責原則(Single Responsibility Principle, SRP)。這個原則指出,一個類或一個模塊應該有且只有一個引起它變化的原因。換句話説,一個函數應該只做一件事,並把它做好。
更直觀地總結兩者的區別,總結了一個表格:
| 特性 | cv2.imread |
cv2.imdecode |
|---|---|---|
| 主要使用場景 | 從本地文件路徑加載圖像。 | 從內存中的字節緩衝區解碼圖像。 |
| 輸入參數類型 | string (文件路徑) |
numpy.ndarray (一維, dtype=np.uint8) |
| 承擔的職責 | 文件I/O 2. 圖像解碼 | 圖像解碼 |
| 抽象級別 | 高層 (便利的封裝函數) | 底層 (核心解碼引擎) |
| 靈活性 | 侷限於本地文件系統。 | 高度靈活,可處理來自任何來源的數據。 |
以上就是本文的全部內容了,想了解更多 OpenCV Python 的工友歡迎關注 《OpenCV Python 中文教程》
點贊 + 關注 + 收藏 = 學會了