博客 / 詳情

返回

『OpenCV-Python』加載網絡圖片

點贊 + 關注 + 收藏 = 學會了

前面介紹過在 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.imreadflags 相同)。是一個整數,它像一個指令開關,告訴 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.imreadcv2.imdecode 兩個API?

cv2.imreadcv2.imdecode似乎在做同樣的事情——將某種格式的數據變成OpenCV可以處理的圖像矩陣。那麼,為什麼需要兩個獨立的函數呢?這並非冗餘設計,而是體現了軟件工程中一個極其重要的原則:單一職責原則(Single Responsibility Principle, SRP)。這個原則指出,一個類或一個模塊應該有且只有一個引起它變化的原因。換句話説,一個函數應該只做一件事,並把它做好。

更直觀地總結兩者的區別,總結了一個表格:

特性 cv2.imread cv2.imdecode
主要使用場景 從本地文件路徑加載圖像。 從內存中的字節緩衝區解碼圖像。
輸入參數類型 string (文件路徑) numpy.ndarray (一維, dtype=np.uint8)
承擔的職責 文件I/O 2. 圖像解碼 圖像解碼
抽象級別 高層 (便利的封裝函數) 底層 (核心解碼引擎)
靈活性 侷限於本地文件系統。 高度靈活,可處理來自任何來源的數據。

以上就是本文的全部內容了,想了解更多 OpenCV Python 的工友歡迎關注 《OpenCV Python 中文教程》

點贊 + 關注 + 收藏 = 學會了

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.