看了好多博客,最終發現得好好研究一個人的博客并去做實驗,才能達到最好的學習效果。
https://blog.csdn.net/on2way/article/details/46812121
參考其博客,并發現一個文檔網址:
https://docs.opencv.org/3.2.0/d7/d4d/tutorial_py_thresholding.html
是不錯的學習資料
本片博客主要使用python_opencv嘗試了三種閾值處理方法,現總結如下,并把自己嘗試的代碼附上。
?圖像的閾值處理(python下opencv使用)
1.簡單閾值
簡單閾值最為簡單,選取一個全局閾值,然后把整幅圖像分成非黑即白的二值圖像。函數為
cv.threshold(),該函數有四個參數,第一個為原圖像,第二個進行分類的閾值,第三個是高于(低于)閾值時所賦予的新值,第四個是一個方法選擇參數,常用方法選擇參數有:
- cv2.THRESH_BINARY(黑白二值) 高于閾值的設置為新值,低于閾值的為0
- cv2.THRESH_BINARY_INV(黑白二值反轉) 與上一個反過來
- cv2.THRESH_TRUNC (得到的圖像為多像素值) 高于閾值的全為閾值,低于閾值的不變
- cv2.THRESH_TOZERO 高于閾值的不變,低于閾值的全為0
- cv2.THRESH_TOZERO_INV 與上一個反過來
?
import cv2import numpy as npfrom matplotlib import pyplot as pltimg = cv2.imread("D:\\software_my_programming\\relate_to_irisrecog\\CASIA-Iris-Lamp\\001\\L\\S2001L01.jpg")#讀取圖像,0為灰度圖像,1為彩色圖像ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)ret,thresh2 = cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)ret,thresh3 = cv2.threshold(img,127,255,cv2.THRESH_TRUNC)ret,thresh4 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO)ret,thresh5 = cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)titles = ['img','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']images = [img,thresh1,thresh2,thresh3,thresh4,thresh5]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()
2.自適應閾值
自適應閾值看成是一個局部性的閾值,通過規定一個區域大小,比較這個點與區域大小里面像素點的平均值(或者其他特征)的大小關系確定這個像素點是屬于黑或者白(如果是二值情況)。使用函數為:cv2.adaptiveThreshold() (僅用于灰度圖像)
該函數需要6個參數:
?
- 第一個原始圖像
- 第二個像素值上限
- 第三個自適應方法Adaptive Method:
- — cv2.ADAPTIVE_THRESH_MEAN_C :領域內均值
- —cv2.ADAPTIVE_THRESH_GAUSSIAN_C :領域內像素點加權和,權 重為一個高斯窗口
- 第四個值的賦值方法:只有cv2.THRESH_BINARY 和cv2.THRESH_BINARY_INV
- 第五個Block size:規定領域大小(一個正方形的領域)
- 第六個常數C,閾值等于均值或者加權值減去這個常數(為0相當于閾值 就是求得領域內均值或者加權值)
這種方法理論上得到的效果更好,相當于在動態自適應的調整屬于自己像素點的閾值,而不是整幅圖像都用一個閾值。
?
import cv2import numpy as npfrom matplotlib import pyplot as pltimg = cv2.imread("D:\\software_my_programming\\\relate_to_irisrecog\\CASIA-Iris-Lamp\\001\\L\\S2001L01.jpg",0)#讀取圖像,0為灰度圖像,1為彩色圖像ret,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)thresh2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,\cv2.THRESH_BINARY,11,2)thresh3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\cv2.THRESH_BINARY,11,2)titles = ['img','BINARY','ADAPTIVE_THRESH_MEAN_C','ADAPTIVE_THRESH_GAUSSIAN_C',]images = [img,thresh1,thresh2,thresh3]for i in range(4):plt.subplot(2,2,i+1)plt.imshow(images[i],'gray')plt.title(titles[i])plt.xticks([]),plt.yticks([])plt.show()
3.Otsu’s二值化
前面對于閾值的處理上,我們選擇的閾值都是127,那么實際情況下,怎么去選擇這個127呢?有的圖像可能閾值不是127得到的效果更好。那么這里我們需要算法自己去尋找到一個閾值,而Otsu’s就可以自己找到一個認為最好的閾值。并且Otsu’s非常適合于圖像灰度直方圖具有雙峰的情況,他會在雙峰之間找到一個值作為閾值,對于非雙峰圖像,可能并不是很好用。那么經過Otsu’s得到的那個閾值就是函數cv2.threshold的第一個參數了。因為Otsu’s方法會產生一個閾值,那么函數cv2.threshold的的第二個參數(設置閾值)就是0了,并且在cv2.threshold的方法參數中還得加上語句cv2.THRESH_OTSU。那么什么是雙峰圖像(只能是灰度圖像才有),就是圖像的灰度統計圖中可以明顯看出只有兩個波峰。
?
import cv2import numpy as npfrom matplotlib import pyplot as pltimg = cv2.imread("D:\\software_my_programming\\\relate_to_irisrecog\\CASIA-Iris-Lamp\\001\\L\\S2001L01.jpg",0)#讀取圖像,0為灰度圖像,1為彩色圖像ret1,thresh1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)#簡單濾波ret2,thresh2 = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)#Ostu濾波print(ret2)plt.subplot(221),plt.imshow(img,'gray')plt.subplot(222),plt.hist(img.ravel(),256)#該方法將矩陣轉化為一維plt.subplot(223),plt.imshow(thresh1,'gray')plt.subplot(224),plt.imshow(thresh2,'gray')plt.show()
?
?
?
總結
以上是生活随笔為你收集整理的opencv_python阈值处理的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。