目錄
閾值處理
一.threshold函數(shù)
1.二值化閾值處理(cv2.THRESH_BINARY)
2.反二值化閾值處理( cv2.THRESH_BINARY_INV)
3.截斷閾值化處理(cv2.THRESH_TRUNC)
4.超閾值零處理(cv2.THRESH_TOZERO_INV)
5.低閾值零處理(cv2.THRESH_TOZERO)
?二.自適應(yīng)閾值處理
?三.Otsu處理
閾值處理
閾值處理是指剔除圖像內(nèi)像素高于一定值或低于一定值的像素點。例如,設(shè)定閾值為127,然后:
1.將圖像內(nèi)所有像素值大于127的像素點的值設(shè)為255
2.將圖像內(nèi)所有像素值小于或等于127的像素點的值設(shè)為0
通過上述方式能夠得到一幅二值圖像。
一.threshold函數(shù)
OpenCV3.0使用cv2.threshold函數(shù)進行閾值化處理,該函數(shù)的語法格式為:
retval, dst = cv2.threshold(src, thresh, maxval, type)
式中:
retval代表返回的閾值。
dst代表閾值分割結(jié)果圖像,與原始圖像具有相同的大小和類型。
src代表要進行閾值分割的圖像,可以是多通道的,8位或32位浮點型數(shù)值。
thresh代表要設(shè)定的閾值。
maxval代表當(dāng)type參數(shù)為THRESH_BINARY或者THRESH_BINARY_INV類型時,需要設(shè)定的最大值。
type代閾值分割的類型(cv2.THRESH_BINARY,? cv2.THRESH_BINARY_INV,? cv2.THRESH_TRUNC,??cv2.THRESH_TOZERO_INV,??cv2.THRESH_TOZERO,??cv2.THRESH_MASK,?cv2.THRESH_OTSU,?cv2.THRESH_TRIANGLE)。
1.二值化閾值處理(cv2.THRESH_BINARY)
二值化閾值處理會將原始圖像處理為僅有兩個值的二值圖像,其針對的像素點的處理方式為:
1)對于灰度值大于閾值thresh的像素點,將其灰度值設(shè)定為最大值。
2)對于灰度值小于或等于閾值thresh的像素點,將其灰度值設(shè)定為0。
使用函數(shù)cv2.threshold()對數(shù)組進行二值化閾值處理,觀察處理結(jié)果:
import cv2
import numpy as np
# 使用函數(shù)cv2.threshold()對數(shù)組進行二值化閾值處理
img = np.random.randint(0, 256, size=[4,5], dtype=np.uint8)
t, rst = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
print("img=\n", img)
print("t=", t)
print("rst=", rst)
使用函數(shù)cv2.threshold()對圖像進行二值化閾值處理,觀察處理結(jié)果:
import cv2
# 使用函數(shù)cv2.threshold()對圖像進行二值化閾值處理
img = cv2.imread("../imgs/girl2.png")
t, rst = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
cv2.imshow("img", img)
cv2.imshow("rst", rst)
cv2.waitKey()
cv2.destroyAllWindows()
左圖是原始圖像,右圖是二值化閾值處理結(jié)果。?
2.反二值化閾值處理( cv2.THRESH_BINARY_INV)
反二值化閾值處理的結(jié)果也是僅有兩個值的二值圖像,與二值化閾值處理的區(qū)別在于,二者對像素值的處理方式不同。反二值化閾值處理針對像素點的處理方式為:
1)對于灰度值大于閾值的像素點,將其值設(shè)定為0。
2)對于灰度值小于或等于閾值的像素點,將其值設(shè)為255。
使用函數(shù)cv2.threshold()對數(shù)組進行反二值化閾值處理,觀察處理結(jié)果:
import cv2
import numpy as np
# 使用函數(shù)cv2.threshold()對數(shù)組進行反二值化閾值處理
img = np.random.randint(0, 256, size=[4,5], dtype=np.uint8)
t, rst = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
print("img=\n", img)
print("t=", t)
print("rst=", rst)
?
使用函數(shù)cv2.threshold()對圖像進行反二值化閾值處理,觀察處理結(jié)果:
import cv2
# 使用函數(shù)cv2.threshold()對圖像進行反二值化閾值處理
img = cv2.imread("../imgs/02.jpg")
t, rst = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
cv2.imshow("img", img)
cv2.imshow("rst", rst)
cv2.waitKey()
cv2.destroyAllWindows()
?其中,左圖為原圖,右圖為反二值化閾值處理結(jié)果。
3.截斷閾值化處理(cv2.THRESH_TRUNC)
截斷閾值化處理會將圖像中大于閾值的像素點設(shè)為值設(shè)定為閾值,小于或等于該閾值的像素點的值保持不變。
1)對于像素值大于127的像素點,其像素值被設(shè)定為127。
2)對于像素值小于或等于127的像素點,其像素值保持改變。
使用函數(shù)cv2.threshold()對數(shù)組進行截斷閾值化處理,觀察處理結(jié)果:
import cv2
import numpy as np
# 使用函數(shù)cv2.threshold()對數(shù)組進行截斷閾值化處理
img = np.random.randint(0, 256, size=[4,5], dtype=np.uint8)
t, rst = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)
print("img=\n", img)
print("t=", t)
print("rst=", rst)
?使用函數(shù)cv2.threshold()對圖像進行截斷閾值化處理,觀察處理結(jié)果:
import cv2
# 使用函數(shù)cv2.threshold()對圖像進行截斷閾值化處理
img = cv2.imread("../imgs/girl2.png")
t, rst = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)
cv2.imshow("img", img)
cv2.imshow("rst", rst)
cv2.waitKey()
cv2.destroyAllWindows()
左圖為原始圖像,右圖為截斷閾值化處理結(jié)果
4.超閾值零處理(cv2.THRESH_TOZERO_INV)
超閾值零處理會將圖像中大于閾值的像素點的值處理為0,小于或等于該閾值的像素點的值保持不變。即先選定一個閾值,然后對圖像做如下處理:
1)對于像素值大于閾值的像素點,其像素值將被處理為0.
2)對于像素值小于或等于閾值的像素點,其像素值保持不變。
使用函數(shù)cv2.threshold()對數(shù)組進行超閾值零處理,觀察處理結(jié)果:
import cv2
import numpy as np
# 使用函數(shù)cv2.threshold()對數(shù)組進行超閾值零處理
img = np.random.randint(0, 256, size=[4,5], dtype=np.uint8)
t, rst = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)
print("img=\n", img)
print("t=", t)
print("rst=", rst)
使用函數(shù)cv2.threshold()對圖像進行超閾值零處理,觀察處理結(jié)果:
import cv2
# 使用函數(shù)cv2.threshold()對圖像進行超閾值零處理
img = cv2.imread("../imgs/girl2.png")
t, rst = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)
cv2.imshow("img", img)
cv2.imshow("rst", rst)
cv2.waitKey()
cv2.destroyAllWindows()
?左圖為原始圖像,右圖為超閾值零處理的結(jié)果。
5.低閾值零處理(cv2.THRESH_TOZERO)
低閾值處理會將圖像中小于或等于閾值的像素點的值處理為0,大于閾值的像素點的值保持不變。
使用函數(shù)cv2.threshold()對數(shù)組進行低閾值零處理,觀察處理結(jié)果:
import cv2
import numpy as np
# 使用函數(shù)cv2.threshold()對數(shù)組進行低閾值零處理
img = np.random.randint(0, 256, size=[4,5], dtype=np.uint8)
t, rst = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)
print("img=\n", img)
print("t=", t)
print("rst=", rst)
?使用函數(shù)cv2.threshold()對圖像進行低閾值零處理,觀察處理結(jié)果:
import cv2
# 使用函數(shù)cv2.threshold()對圖像進行低閾值零處理
img = cv2.imread("../imgs/girl2.png")
t, rst = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)
cv2.imshow("img", img)
cv2.imshow("rst", rst)
cv2.waitKey()
cv2.destroyAllWindows()
?二.自適應(yīng)閾值處理
對于色彩均衡的圖像,直接使用一個閾值就能完成對圖像的閾值化處理。但是,有時,圖像的色彩是不均衡的,此時如果只使用一個閾值,就無法得到清晰有效的閾值分割結(jié)果圖像。
有一種改進的閾值處理技術(shù),其使用變化的閾值完成對圖像的閾值處理,這種技術(shù)被稱為自適應(yīng)閾值處理。在進行閾值處理時,自適應(yīng)閾值處理的方式通過計算每個像素點周圍臨近區(qū)域的加權(quán)平均值獲得閾值,并使用該閾值對當(dāng)前像素點進行處理。與普通的閾值處理方法相比,自適應(yīng)閾值處理能夠更好地處理明暗差異較大的圖像。
OpenCV提供了函數(shù)cv2.adaptiveThreshold來實現(xiàn)自適應(yīng)閾值處理,該函數(shù)的語法格式為:
dst = cv.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C)
式中:
dst代表自適應(yīng)閾值處理結(jié)果。
src代表要進行處理的原始圖像。需要注意的是,該圖像必須是8位單通道的圖像。
maxValue代表最大值。
adaptiveMethod代表自適應(yīng)的方法。
thresholdType代表閾值處理方式,該值必須是cv2.THRESH_BINARY或者 cv2.THRESH_BINARY_INV中的一個。
blockSize代表塊大小。表示一個像素在計算其閾值時所使用的領(lǐng)域尺寸,通常為3、5、7等。
C是常量。
函數(shù)cv2.adaptiveThreshold()根據(jù)參數(shù)adaptiveMethod來確定自適應(yīng)閾值的計算方法,函數(shù)包含cv2.ADAPTIVE_THRESH_MEAN_C和cv2.ADAPTIVE_THRESH_GAUSSIAN_C兩種不同的方法。這兩種方法都是逐個計算像素地計算自適應(yīng)閾值,自適應(yīng)閾值等于每個像素由參數(shù)blockSize所指定領(lǐng)域的加權(quán)平均值減去常量C。兩種不同的方法在計算領(lǐng)域的加權(quán)平均值時所采用的方式不同:
cv2.ADAPTIVE_THRESH_MEAN_C:領(lǐng)域所有像素點的權(quán)重值是一致。
cv2.ADAPTIVE_THRESH_GAUSSIAN_C:與領(lǐng)域各個像素點到中心點的距離有關(guān),通過高斯方程得到各個點的權(quán)重值。
對一幅圖像分別使用二值化閾值函數(shù)cv2.threshold()和自適應(yīng)閾值函數(shù)cv2.adaptiveThreshold()進行處理,觀察處理結(jié)果的差異:
import cv2
img = cv2.imread("../imgs/girl2.png", 0)
t1, thd = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
athdMEAN = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 3)
athdGAUS = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 5, 3)
cv2.imshow("img", img)
cv2.imshow("thd", thd)
cv2.imshow("athdMEAN", athdMEAN)
cv2.imshow("athdGAUS", athdGAUS)
cv2.waitKey()
cv2.destroyAllWindows()
從左往右依次是原圖、二值化閾值處理結(jié)果、cv2.ADAPTIVE_THRESH_MEAN_C處理結(jié)果、cv2.ADAPTIVE_THRESH_GAUSSIAN_C處理結(jié)果。
?三.Otsu處理
在使用函數(shù)cv2.threshold()進行閾值處理時,需要自定義一個閾值,并以此閾值作為圖像閾值處理的依據(jù)。通常情況下處理的圖像都是色彩均衡的,這時直接將閾值設(shè)為127是比較合適的。
但是,有時圖像灰度級的分布是不均衡的,如果此時還將閾值設(shè)為127,那么閾處理的結(jié)果就是失敗的。
簡而言之,Otsu方法會遍歷所有可能閾值,從而找到最佳的閾值。在使用Otsu方法時,要把閾值設(shè)為0。此時的函數(shù)cv2.threshold()會自動尋找最優(yōu)閾值,并將該閾值返回。
t, otsu = cv2.threshold(img, 0, 255, cv2>THRESH_BINARY + cv2.THRESH_OTSU)
與普通閾值分割的不同之處在于:
參數(shù)type增加了一個參數(shù)值“cv2.THRESH_OTSU”。
設(shè)定的閾值為0。
返回值t是Otsu方法計算得到并使用的最優(yōu)閾值。
import cv2
import numpy as np
img = np.zeros((5, 5), dtype=np.uint8)
img[0:6, 0:6] = 123
img[2:6, 2:6] = 126
print("img=\n", img)
t1, thd = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
print("thd=", thd)
t2, otsu = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
print("otsu=", otsu)
分別對一幅圖像進行普通的二值化閾值處理和Otsu閾值處理,觀察處理結(jié)果的差異:
import cv2
img = cv2.imread("../imgs/02.jpg", 0)
t1, thd = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
t2, otsu = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
cv2.imshow("img", img)
cv2.imshow("thd", thd)
cv2.imshow("otsu", otsu)
cv2.waitKey()
cv2.destroyAllWindows()
文章來源:http://www.zghlxwxcb.cn/news/detail-516961.html
?從左往右依次是原圖、普通二值化閾值處理結(jié)果和Otsu處理結(jié)果。文章來源地址http://www.zghlxwxcb.cn/news/detail-516961.html
到了這里,關(guān)于OpenCV閾值處理(threshold函數(shù)、自適應(yīng)閾值處理、Otsu處理)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!