添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
慷慨的黄豆  ·  Solved: HubSpot ...·  3 月前    · 
打酱油的菠萝  ·  Four Points by ...·  4 月前    · 
耍酷的红烧肉  ·  华为手环3 ...·  5 月前    · 

二值化黑白影像

這篇教學會介紹如何運用 OpenCV 裡的 threshold() 方法,將影像上轉換為二值化的黑白影像,進一步使用 adaptiveThreshold() 自適應二值化的方法,產生效果更好的黑白影像。

快速導覽:

  • 什麼是二值化 ( 閾值二進制 )?
  • threshold() 產生黑白影像
  • adaptiveThreshold() 自適應二值化
  • 影片的二值化黑白效果
  • 因為程式中的 OpenCV 會需要使用鏡頭或 GPU,所以請 使用本機環境 ( 參考: 使用 Python 虛擬環境 ) 或 使用 Anaconda Jupyter 進行實作 ( 參考: 使用 Anaconda ) ,並 安裝 OpenCV 函式庫 ( 參考: OpenCV 函式庫 )。

    什麼是二值化 ( 閾值二進制 )?

    二值化又稱為「閾值二進制」( 閾發音 ㄩ、 ),是一種簡單的圖像分割方法,二值化會根據「閾值」( 類似臨界值 ) 進行轉換, 例如某個像素的灰度值大於閾值,則轉換為黑色,如果這個像素的灰度小於閾值則轉換為白色,進而實現二值化的轉換效果 ,經過二值化轉換的圖片,通常只會剩下黑和白兩個值。

    許多影像辨識或影像處理的領域 ( 例如輪廓偵測、邊緣偵測...等 ),都會使用二值化影像進行運算,有些影像處理甚至會先將圖片二值化後,再進行後續的計算處理。

    threshold() 產生黑白影像

    threshold() 方法可以 將灰階的影像,以二值化的方式轉換成黑白影像 ,使用方法如下:

    ret, output = cv2.THRESH_BINARY(img, thresh, maxval, type)
    # ret 是否成功轉換,成功 True,失敗 False
    # img 來源影像
    # thresh 閾值,通常設定 127
    # maxval 最大灰度,通常設定 255
    # type 轉換方式
    

    threshold() 方法有下列幾種轉換方式,使用 127 和 255 作為說明範例 ( 參考 cv::ThresholdTypes ):

    cv2.THRESH_BINARY 如果大於 127 就等於 255,反之等於 0。 cv2.THRESH_BINARY_INV 如果大於 127 就等於 0,反之等於 255。 cv2.THRESH_TRUNC 如果大於 127 就等於 127,反之數值不變。 cv2.THRESH_TOZERO 如果大於 127 數值不變,反之數值等於 0。 cv2.THRESH_TOZERO_INV 如果大於 127 等於 0,反之數值不變。

    下方的程式執行後,會將一張黑白漸層的圖片,根據不同的轉換方式,轉換成二值化的黑白圖片 ( 注意,轉換前都要先將圖片轉換成灰階色彩 )。

    範例圖片: 下載連結

    import cv2
    img = cv2.imread('gradient.png')
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY); # 轉換前,都先將圖片轉換成灰階色彩
    ret, output1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)     # 如果大於 127 就等於 255,反之等於 0。
    ret, output2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV) # 如果大於 127 就等於 0,反之等於 255。
    ret, output3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)      # 如果大於 127 就等於 127,反之數值不變。
    ret, output4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)     # 如果大於 127 數值不變,反之數值等於 0。
    ret, output5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV) # 如果大於 127 等於 0,反之數值不變。
    cv2.imshow('oxxostudio', img)
    cv2.imshow('oxxostudio1', output1)
    cv2.imshow('oxxostudio2', output2)
    cv2.imshow('oxxostudio3', output3)
    cv2.imshow('oxxostudio4', output4)
    cv2.imshow('oxxostudio5', output5)
    cv2.waitKey(0)    # 按下任意鍵停止
    cv2.destroyAllWindows()
    

    adaptiveThreshold() 自適應二值化

    使用 threshold() 方法轉換灰階的影像時,必須手動設定灰度和閾值,比較適合內容較單純的影像,如果遇到內容比較複雜的影像,每個像素間可能都有關連性,這時就可以使用 adaptiveThreshold() 方法,進行自適應二值化的轉換,自適應二值化可以根據指定大小的區域平均值,或是整體影像的高斯平均值,判斷所需的灰度和閾值,進而產生更好的轉換效果

    adaptiveThreshold() 的使用方法如下:

    cv2.adaptiveThreshold(img, maxValue, adaptiveMethod, thresholdType, blockSize, C)
    # img 來源影像
    # maxValue 最大灰度,通常設定 255
    # adaptiveMethod 自適應二值化計算方法
    # thresholdType 二值化轉換方式
    # blockSize 轉換區域大小,通常設定 11
    # C 偏移量,通常設定 2
    

    使用時 thresholdType 為二值化轉換方式,可以參考上方轉換方式列表,adaptiveMethod 自適應二值化計算方法有兩種,分別是:

    自適應二值化方法 cv2.ADAPTIVE_THRESH_MEAN_C 使用區域平均值。 cv2.ADAPTIVE_THRESH_GAUSSIAN_C 使用整體高斯平均值。

    下方的程式執行後,會將一張數獨的照片,根據不同的自適應二值化轉換方式,轉換成黑白圖片 ( 注意,轉換前都要先將圖片轉換成灰階色彩 )。

    範例圖片:下載連結

    import cv2
    img = cv2.imread('test.jpg')
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY); # 轉換前,都先將圖片轉換成灰階色彩
    ret, output1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
    output2 = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
    output3 = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
    cv2.imshow('oxxostudio', img)
    cv2.imshow('oxxostudio1', output1)
    cv2.imshow('oxxostudio2', output2)
    cv2.imshow('oxxostudio3', output3)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    如果要降低圖片的雜訊,可以使用 cv2.medianBlur() 先將圖片模糊化,下方的範例可以看見有模糊化和沒有模糊化的差異:

    參考:影像模糊化

    import cv2
    img = cv2.imread('test.jpg')
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY);
    output1 = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
    img_gray2 = cv2.medianBlur(img_gray, 5)   # 模糊化
    output2 = cv2.adaptiveThreshold(img_gray2, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
    cv2.imshow('oxxostudio1', output1)
    cv2.imshow('oxxostudio2', output2)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    延伸「讀取並播放影片」文章的範例,在程式碼中使用自適應二值化方法,就能將電腦鏡頭拍攝的畫面,即時轉換成二值化黑白的影像。

    import cv2
    cap = cv2.VideoCapture(0)
    if not cap.isOpened():
        print("Cannot open camera")
        exit()
    while True:
        ret, frame = cap.read()
        if not ret:
            print("Cannot receive frame")
            break
        # 套用自適應二值化黑白影像
        img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY);
        img_gray = cv2.medianBlur(img_gray, 5)
        output = cv2.adaptiveThreshold(img_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
        cv2.imshow('oxxostudio', output)
        if cv2.waitKey(1) == ord('q'):
            break       # 按下 q 鍵停止
    cap.release()
    cv2.destroyAllWindows()
    
  • https://docs.opencv.org/4.x/d7/d4d/tutorial_py_thresholding.html
  • 如果有任何建議或問題,可傳送「意見表單」給我,謝謝~

    Python 教學

    Python 學習導讀 關於 Python 使用 Google Colab 使用 Anaconda 使用 Python 虛擬環境 Python 範例集錦 變數 variable 變數 ( 全域、區域 ) 數字 number 文字與字串 string 文字與字串 ( 常用方法 ) 文字與字串 ( 格式化 ) 串列 list 串列 ( 常用方法 ) 元組/數組 tuple 字典 dictionary 集合 set 縮排和註解 運算子 operator 邏輯判斷 ( if、elif、else ) 邏輯判斷 ( and 和 or ) 重複迴圈 ( for、while ) 例外處理 ( try、except ) 生成式 comprehension 物件類別 class 物件繼承 inheritance 匯入模組 import 函式 function 匿名函式 lambda 遞迴 recursion 產生器 generator 裝飾器 decorator 閉包 closure

    內建函式&方法

    輸入與輸出 字串操作與轉換 迭代物件轉換 迭代物件操作 檔案讀寫 ( open ) eval() 與 exec()

    標準函式庫&模組

    隨機數 random 數學 math 數學統計函式 statistics 時間與日期 datetime 時間處理 time 日曆 calendar 使用正規表達式 re 檔案操作 os 查找匹配檔案 glob 壓縮檔案 zipfile 高階檔案操作 shutil 高效迭代器 itertools 容器資料型態 collections CSV 檔案操作 JSON 檔案操作 threading 多執行緒處理 concurrent.futures