opencv基礎 threshold實現圖像閾值輸出·基礎性講解(內含gif效果圖)

                         QQ:3020889729                                                                                 小蔡

講解目的展示

在這裏插入圖片描述
(以上展示代碼是後邊實例的整合——簡單的把彩色/灰度圖像放在不同的數組中,然後遍歷即可)
在圖像處理中,常常對圖像進行特徵處理,而閾值也是圖像的特徵屬性——每一個像素對應着一定的數據——灰度圖像爲8位的強度數據,彩色圖像爲32位的BGR數據。
生活中我們其實在處理問題時經常用到閾值處理——比如:多個裁判評分去掉最低分和最高分,再計算實際數據。比如,一個公司在起步階段,需要一部分技術人員——只有超過預期能力纔會被選擇,否則就是被排除掉——當然,我的比喻可能不太對,但是呢,就是想希望這樣能讓你明白——opencv他也是這樣工作的,至於一些特殊的閾值比較方式就是opencv爲了解決問題所應用設計的了。

閾值函數——cv.threshold應用圖像閾值操作

函數參數簡介

輸入參數如下:

def threshold(src, thresh, maxval, type, dst=None): # real signature unknown; restored from __doc__
  • 輸入圖像——受後邊的type影響——灰度圖像總適用,彩色圖像就不一定了
  • 閾值
  • 滿足閾值的最大輸出值
  • 閾值類型——或者說,選擇一種閾值判定方法
  • 最後是輸出——默認返回接受即可,不用設置的

輸出參數:

  • 第一個參數爲設置的閾值
  • 第二個參數爲閾值處理後的圖像

下面提一下閾值類型,我覺得很有必要——

閾值類型基本介紹

這些類型都跟實際需要的情況相關——自由選擇(一般選擇前5種,末尾支持的兩種可以作爲添加條件,補充閾值操作)。

需要知道的是,前五種除了應用灰度圖像外,也滿足彩色圖像——而最後兩種僅僅是二值操作,所以就只適用8位的灰度圖像了——即對強度數據進行閾值操作。
以下類型解釋——以表達式爲準,文字僅僅作爲參考和促進理解。

  • 在這裏插入圖片描述
    這個閾值類型指的是——當輸入圖像大於我們設置的閾值時,就把對應像素數據設置爲最大值,否則爲0。

  • 在這裏插入圖片描述
    這個閾值類型與上一個相反——當輸入圖像大於我們設置的閾值時,就把對應像素數據設置爲0,否則爲最大值。

  • 在這裏插入圖片描述
    這個閾值類型指——當輸入圖像大於我們設置的閾值時,就把對應像素數據設置爲我們設置的值(maxvalue),否則爲圖像本身的值。

  • 在這裏插入圖片描述
    這個閾值類型指——當輸入圖像大於我們設置的閾值時,就把對應像素數據保留,否則爲0。

  • 在這裏插入圖片描述
    這個閾值類型指——當輸入圖像大於我們設置的閾值時,就把對應像素數據設置爲0,否則爲原始數據。

  • Python: cv.THRESH_MASK——不支持——這個不多說明,因爲我知道的也是不多,後邊有機會補正。

  • Python: cv.THRESH_OTSU——不支持32位的彩色圖像, 僅僅支持8位灰度圖像

  • Python: cv.THRESH_TRIANGLE——不支持32位的彩色圖像, 僅僅支持8位灰度圖像

代碼實例

灰度圖像實例

import cv2 as cv

img = cv.imread('../imag_in_save/images.png')
img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)  # 這樣可以獲得灰度圖像
# 也可以用img = cv.imread('../imag_in_save/images.png', 0)直接獲得
# 我是爲了最後邊的樣例做灰度變化和彩色變化對比做的準備操作的——即程序保留有彩色圖像的數據

ret1, thresh1 = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)  # src(x,y) > 127 => dst(輸出)(x,y) = 255
cv.imshow('imag', img)
cv.imshow('imag3', thresh1)  # 輸出閾值處理的圖像

cv.waitKey(0)  # 等待按鍵輸入
cv.destroyAllWindows()

效果:
在這裏插入圖片描述
原圖
在這裏插入圖片描述

遍歷(灰度)所有情況——所有閾值類型效果展示(以及代碼)

import cv2 as cv


if __name__ == "__main__":
    img = cv.imread('../imag_in_save/images.png')
    img_gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    # 依次遍歷轉換——可以直接使用list,但是我爲了展示就獨立寫了
    ret1, thresh1 = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY)  # 滿足閾值設置255(我們設置的最大值)反之爲0
    ret2, thresh2 = cv.threshold(img_gray, 127, 255, cv.THRESH_BINARY_INV)  # 滿足閾值設置0,反之255
    ret3, thresh3 = cv.threshold(img_gray, 127, 255, cv.THRESH_MASK)  # 順便演示一下,具體該用在哪些地方,後邊遇到了回來修正
    ret4, thresh4 = cv.threshold(img_gray, 127, 255, cv.THRESH_OTSU)  # 使用otus算法取最優閾值_只適合灰度圖像(文末說明,篇幅)
    ret5, thresh5 = cv.threshold(img_gray, 127, 255, cv.THRESH_TOZERO)  # 滿足保留原數據,否則爲0,與設置的最值255無關了
    ret6, thresh6 = cv.threshold(img_gray, 127, 255, cv.THRESH_TOZERO_INV)  # 與THRESH_TOZERO相反
    ret7, thresh7 = cv.threshold(img_gray, 127, 255, cv.THRESH_TRIANGLE)  # 使用三角算法取最優閾值_只適合灰度圖像(文末說明,篇幅)
    ret8, thresh8 = cv.threshold(img_gray, 127, 255, cv.THRESH_TRUNC)  # 滿足閾值設置255,反之保留原數據
    title = ['THRESH_BINARY', 'THRESH_BINARY_INV', 'THRESH_MASK', 'THRESH_OTSU', 'THRESH_TOZERO', 'THRESH_TOZERO_INV',
             'THRESH_TRIANGLE', 'THRESH_TRUNC']
    img_list = [thresh1, thresh2, thresh3, thresh4, thresh5, thresh6, thresh7, thresh8]

    # 字體顏色根據圖像本身來傳入對應的數據類型——彩色爲三元元組
    # 灰度圖像——傳入強度即可
    for i in range(0, 8):  # 往圖片上寫文字——即使用的閾值類型
        cv.putText(img_list[i], title[i], (25, 60), cv.FONT_HERSHEY_COMPLEX_SMALL, 1, 220, 2, cv.LINE_AA)
    i = 0
    while True:  # 遍歷展示
        cv.imshow('imag', img_list[i])
        k = cv.waitKey(1000) & 0xFF
        if k == 27:
            break
        i += 1
        if i == 8:
            i = 0
    cv.destroyAllWindows()

在這裏插入代碼片

彩色圖像的實例(類似灰度,只是閾值類型少了兩項)

實現還是和之前的灰度圖像的閾值操作一般無二。

import cv2 as cv


if __name__ == "__main__":
    img = cv.imread('../imag_in_save/images.png')
    ret1, thresh1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)  # 滿足閾值設置255(我們設置的最大值)反之爲0
    cv.imshow('imag', img)
    cv.imshow('imag_THRESH_BINARY', thresh1)
    cv.waitKey(0)
    cv.destroyAllWindows()

效果:在實現效果中去體會參數變化會更直接些。
在這裏插入圖片描述
原圖
在這裏插入圖片描述

遍歷(灰度)所有情況——所有閾值類型效果展示(以及代碼)

import cv2 as cv


if __name__ == "__main__":
    img = cv.imread('../imag_in_save/images.png')
    ret1, thresh1 = cv.threshold(img, 127, 255, cv.THRESH_BINARY)  # 滿足閾值設置255(我們設置的最大值)反之爲0
    ret2, thresh2 = cv.threshold(img, 127, 255, cv.THRESH_BINARY_INV)  
    ret3, thresh3 = cv.threshold(img, 127, 255, cv.THRESH_MASK)  # 順便演示一下
    ret4, thresh4 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO) 
    ret5, thresh5 = cv.threshold(img, 127, 255, cv.THRESH_TOZERO_INV)  # 與THRESH_TOZERO相反
    ret6, thresh6 = cv.threshold(img, 127, 255, cv.THRESH_TRUNC)  
    title = ['THRESH_BINARY', 'THRESH_BINARY_INV', 'THRESH_MASK', 'THRESH_TOZERO', 'THRESH_TOZERO_INV', 'THRESH_TRUNC']
    img_list = [thresh1, thresh2, thresh3, thresh4, thresh5, thresh6]

    # 字體顏色根據圖像本身來傳入對應的數據類型——彩色爲三元元組
    # 灰度圖像——傳入強度即可
    for i in range(0, 6):  # 往圖片上寫文字——即使用的閾值類型
        cv.putText(img_list[i], title[i], (25, 60), cv.FONT_HERSHEY_COMPLEX_SMALL, 1, (40, 180, 80), 2, cv.LINE_AA)
    i = 0
    while True:  # 遍歷展示
        cv.imshow('imag', img_list[i])
        k = cv.waitKey(1200) & 0xFF
        if k == 27:
            break
        i += 1
        if i == 6:
            i = 0
    cv.destroyAllWindows()

效果:
在這裏插入圖片描述

補充:OTSU算法作用過程的簡介

在這裏插入圖片描述
這次講解就到這裏了——希望能幫助到你哪怕一點。後期有應用,我會補充這一章節的實踐操作部分。(前邊寫的文章我也會慢慢積累,然後進行修改訂正的。)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章