您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關(guān)怎么在Python中利用opencv對圖像閾值進行處理,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。
(一)簡單閾值
簡單閾值當然是最簡單,選取一個全局閾值,然后就把整幅圖像分成了非黑即白的二值圖像了。函數(shù)為cv2.threshold()
這個函數(shù)有四個參數(shù),第一個原圖像,第二個進行分類的閾值,第三個是高于(低于)閾值時賦予的新值,第四個是一個方法選擇參數(shù),常用的有:
cv2.THRESH_BINARY(黑白二值)
cv2.THRESH_BINARY_INV(黑白二值反轉(zhuǎn))
cv2.THRESH_TRUNC (得到的圖像為多像素值)
cv2.THRESH_TOZERO
cv2.THRESH_TOZERO_INV
該函數(shù)有兩個返回值,第一個retVal(得到的閾值值(在后面一個方法中會用到)),第二個就是閾值化后的圖像。
一個實例如下:
import cv2 import matplotlib.pyplot as plt img = cv2.imread('flower.jpg',0) #直接讀為灰度圖像 ret,thresh2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY) ret,thresh3 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV) ret,thresh4 = cv2.threshold(img,127,255,cv2.THRESH_TRUNC) ret,thresh5 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO) ret,thresh6 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV) titles = ['img','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV'] images = [img,thresh2,thresh3,thresh4,thresh5,thresh6] for i in range(6): plt.subplot(2,3,i+1),plt.imshow(images[i],'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
可以看到這里把閾值設(shè)置成了127,對于BINARY方法,當圖像中的灰度值大于127的重置像素值為255.
(二)自適應(yīng)閾值:
前面看到簡單閾值是一種全局性的閾值,只需要規(guī)定一個閾值值,整個圖像都和這個閾值比較。而自適應(yīng)閾值可以看成一種局部性的閾值,通過規(guī)定一個區(qū)域大小,比較這個點與區(qū)域大小里面像素點的平均值(或者其他特征)的大小關(guān)系確定這個像素點是屬于黑或者白(如果是二值情況)。使用的函數(shù)為:cv2.adaptiveThreshold()
該函數(shù)需要填6個參數(shù):
第一個原始圖像
第二個像素值上限
第三個自適應(yīng)方法Adaptive Method:
— cv2.ADAPTIVE_THRESH_MEAN_C :領(lǐng)域內(nèi)均值
—cv2.ADAPTIVE_THRESH_GAUSSIAN_C :領(lǐng)域內(nèi)像素點加權(quán)和,權(quán) 重為一個高斯窗口
第四個值的賦值方法:只有cv2.THRESH_BINARY 和cv2.THRESH_BINARY_INV
第五個Block size:規(guī)定領(lǐng)域大?。ㄒ粋€正方形的領(lǐng)域)
第六個常數(shù)C,閾值等于均值或者加權(quán)值減去這個常數(shù)(為0相當于閾值 就是求得領(lǐng)域內(nèi)均值或者加權(quán)值)
這種方法理論上得到的效果更好,相當于在動態(tài)自適應(yīng)的調(diào)整屬于自己像素點的閾值,而不是整幅圖像都用一個閾值。
一個實例如下:
mport cv2 import matplotlib.pyplot as plt img = cv2.imread('flower.jpg',0) #直接讀為灰度圖像 ret,th2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY) th3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,\ cv2.THRESH_BINARY,11,2) #換行符號 \ th4 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\ cv2.THRESH_BINARY,11,2) #換行符號 \ images = [img,th2,th3,th4] plt.figure() for i in xrange(4): plt.subplot(2,2,i+1),plt.imshow(images[i],'gray') plt.show()
可以看到上述窗口大小使用的為11,當窗口越小的時候,得到的圖像越細。想想一下,如果把窗口設(shè)置足夠大以后(不能超過圖像大小),那么得到的結(jié)果可能就和第二幅圖像的相同了。
(三)Otsu's二值化
我們前面說到,cv2.threshold函數(shù)是有兩個返回值的,前面一直用的第二個返回值,也就是閾值處理后的圖像,那么第一個返回值(得到圖像的閾值)將會在這里用到。
前面對于閾值的處理上,我們選擇的閾值都是127,那么實際情況下,怎么去選擇這個127呢?有的圖像可能閾值不是127得到的效果更好。那么這里我們需要算法自己去尋找到一個閾值,而Otsu's就可以自己找到一個認為最好的閾值。并且Otsu's非常適合于圖像灰度直方圖具有雙峰的情況,他會在雙峰之間找到一個值作為閾值,對于非雙峰圖像,可能并不是很好用。那么經(jīng)過Otsu's得到的那個閾值就是函數(shù)cv2.threshold的第一個參數(shù)了。因為Otsu's方法會產(chǎn)生一個閾值,那么函數(shù)cv2.threshold的的第二個參數(shù)(設(shè)置閾值)就是0了,并且在cv2.threshold的方法參數(shù)中還得加上語句cv2.THRESH_OTSU。那么什么是雙峰圖像(只能是灰度圖像才有),就是圖像的灰度統(tǒng)計圖中可以明顯看出只有兩個波峰,比如下面一個圖的灰度直方圖就可以是雙峰圖:
好了現(xiàn)在對這個圖進行Otsu's閾值處理就非常的好,通過函數(shù)cv2.threshold會自動找到一個介于兩波峰之間的閾值。一個實例如下:
import cv2 import matplotlib.pyplot as plt img = cv2.imread('finger.jpg',0) #直接讀為灰度圖像 #簡單濾波 ret1,th2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY) #Otsu 濾波 ret2,th3 = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) print ret2 plt.figure() plt.subplot(221),plt.imshow(img,'gray') plt.subplot(222),plt.hist(img.ravel(),256)#.ravel方法將矩陣轉(zhuǎn)化為一維 plt.subplot(223),plt.imshow(th2,'gray') plt.subplot(224),plt.imshow(th3,'gray')
關(guān)于怎么在Python中利用opencv對圖像閾值進行處理就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。