opencv python如何實現影象二值化
阿新 • • 發佈:2020-02-03
這篇文章主要介紹了opencv python如何實現影象二值化,文中通過示例程式碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
程式碼如下
import cv2 as cv import numpy as np import matplotlib.pyplot as plt # 二值影象就是將灰度圖轉化成黑白圖,沒有灰,在一個值之前為黑,之後為白 # 有全域性和區域性兩種 # 在使用全域性閾值時,我們就是隨便給了一個數來做閾值,那我們怎麼知道我們選取的這個數的好壞呢?答案就是不停的嘗試。 # 如果是一副雙峰影象(簡 單來說雙峰影象是指影象直方圖中存在兩個峰)呢? # 我們豈不是應該在兩個峰之間的峰谷選一個值作為閾值?這就是 Otsu 二值化要做的。 # 簡單來說就是對 一副雙峰影象自動根據其直方圖計算出一個閾值。 # (對於非雙峰影象,這種方法 得到的結果可能會不理想)。 def threshold_demo(image): gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY) # 這個函式的第一個引數就是原影象,原影象應該是灰度圖。 # 第二個引數就是用來對畫素值進行分類的閾值。 # 第三個引數就是當畫素值高於(有時是小於)閾值時應該被賦予的新的畫素值 # 第四個引數來決定閾值方法,見threshold_simple() # ret,binary = cv.threshold(gray,127,255,cv.THRESH_BINARY) ret,cv.THRESH_BINARY | cv.THRESH_OTSU) print("threshold value: %s"%ret) cv.imshow("threshold_demo",binary) def threshold_simple(image): img = cv.cvtColor(image,cv.COLOR_BGR2GRAY) ret,thresh1 = cv.threshold(img,thresh2 = cv.threshold(img,cv.THRESH_BINARY_INV) ret,thresh3 = cv.threshold(img,cv.THRESH_TRUNC) ret,thresh4 = cv.threshold(img,cv.THRESH_TOZERO) ret,thresh5 = cv.threshold(img,cv.THRESH_TOZERO_INV) titles = ['Original Image','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') # 將影象按2x3鋪開 plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show() # 在前面的部分我們使用是全域性閾值,整幅影象採用同一個數作為閾值。 # 當時這種方法並不適應與所有情況,尤其是當同一幅影象上的不同部分的具有不同亮度時。 # 這種情況下我們需要採用自適應閾值。此時的閾值是根據影象上的 每一個小區域計算與其對應的閾值。 # 因此在同一幅影象上的不同區域採用的是不同的閾值,從而使我們能在亮度不同的情況下得到更好的結果。 # 這種方法需要我們指定三個引數,返回值只有一個 # _MEAN_C:閾值取自相鄰區域的平均值,_GAUSSIAN_C:閾值取值相鄰區域 的加權和,權重為一個高斯視窗。 # Block Size - 鄰域大小(用來計算閾值的區域大小)。 # C - 這就是是一個常數,閾值就等於的平均值或者加權平均值減去這個常數。 def threshold_adaptive(image): img = cv.cvtColor(image,cv.COLOR_BGR2GRAY) # 中值濾波 img = cv.medianBlur(img,5) ret,th1 = cv.threshold(img,cv.THRESH_BINARY) # 11 為 Block size,2 為 C 值 th2 = cv.adaptiveThreshold(img,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,11,2) th3 = cv.adaptiveThreshold(img,cv.ADAPTIVE_THRESH_GAUSSIAN_C,2) titles = ['Original Image','Global Threshold (v = 127)','Adaptive Mean Threshold','Adaptive Gaussian Threshold'] images = [img,th1,th2,th3] for i in range(4): plt.subplot(2,2,'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show() def threshold_custom(image): gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY) h,w = gray.shape[:2] m = np.reshape(gray,[1,w*h]) mean = m.sum() / (w*h) # 求出整個灰度影象的平均值 print("mean:",mean) ret,mean,cv.THRESH_BINARY) cv.imshow("threshold_custom",binary) # 將大圖片拆分成小圖片後再用自適應區域性閾值比較好 def big_image_demo(image): print(image.shape) cw = 200 ch = 200 h,w = image.shape[:2] gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY) cv.imshow("big_image_demo_gray",gray) # 將一張圖片每隔ch * cw分成一份 for row in range(0,h,ch): for col in range(0,w,cw): roi = gray[row:row+ch,col:col+cw] dst = cv.adaptiveThreshold(roi,2) gray[row:row + ch,col:col + cw] = dst print(np.std(dst),np.mean(dst)) cv.imwrite("../images/result_big_image.png",gray) def main(): img = cv.imread("../images/02.jpg") # threshold_demo(img) # threshold_simple(img) # threshold_adaptive(img) # threshold_custom(img) src = cv.imread("../images/big_image.jpg") big_image_demo(src) cv.waitKey(0) # 等有鍵輸入或者1000ms後自動將視窗消除,0表示只用鍵輸入結束視窗 cv.destroyAllWindows() # 關閉所有視窗 if __name__ == '__main__': main()
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。