python opencv二值化阈值图像分割
在一般的視覺視覺顏色是由RGB組成的,為了簡化處理的視覺的復雜度,以及得到分割出指定物體的特征形狀,通過二值化的方法更加的高效方便
二值化圖像
-
二值化定義:圖像的二值化,就是將圖像上的像素點的灰度值設置為0或255,也就是將整個圖像呈現出明顯的只有黑和白的視覺效果
-
二值化分割定義:一幅圖像包括目標物體、背景還有噪聲,要想從多值的數字圖像中直接提取出目標物體,常用的方法就是設定一個閾值T,用T將圖像的數據分成兩部分:大于T的像素群和小于T的像素群。這是研究灰度變換的最特殊的方法,稱為圖像的二值化(Binarization)。
重要的函數講解
1.簡單的閾值-(全局閾值):cv2.threshold(src, thresh, maxval, type, dst=None)->retval,dst
參數:
-
src: 指原圖像,原圖像應該是灰度圖
-
thresh:二值化的閾值
-
maxval:超過thresh的像素值設置的最大值
-
type:二值化的方法操作
1)二進制閾值化 THRESH_BINARY - 反二進制閾值化THRESH_BINARY_INV
-
閾值化為0 THRESH_TOZERO
-
反閾值化為0 THRESH_TOZERO_INV
6)大津閾值算法(OTSU):
簡介:大津法(OTSU)可以根據圖像特性,選擇最佳的閾值,不需要人為提供閾值,故它也被認為是圖像分割中閾值選取的最佳算法,計算簡單,不受圖像亮度和對比度的影響。從大津法的原理上來講,該方法又稱作最大類間方差法,按照大津法求得的閾值進行圖像二值化分割后,前景與背景圖像的類間方差最大。適合處理所需提取的前景圖像和背景圖像差距較大的圖像。其函數也十分簡單,只需要把閾值thresh設置為0,然后設置type為cv2.THRESH_BINARY+cv2.THRESH_OTSU,會自動返回一個合適的閾值。
ret2,th2 =cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU) -
dst - 輸出數組/圖像(與src相同大小和類型以及相同通道數的數組/圖像)
3)截斷閾值化 THRESH_TRUNC
返回值:
- retval - 閾值 thresh
- dst - 經函數處理后的圖像 image
2.局部閾值法 : 當圖像的色彩分布不均衡時,使用全局閾值處理的效果不是很好,這是使用局部閾值處理來進行分割,可以產生很好的效果。
局部閾值的處理原理是,針對每一個像素點專門配置一個閾值來進行處理,這些閾值就構成了和原圖像維度相同的矩陣。
cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C, dst=None)
參數:
- src:原圖像。必須是8位單通道的圖像。
- maxval:最大值。一般情況下為255
- adaptiveMethod:自適應方法。高斯閾值算法:ADAPTIVE_THRESH_GAUSSIAN_C、平均閾值算法:ADAPTIVE_THRESH_MEAN_C
- thresholdType:閾值處理方法。
- blockSize:塊的大小。必須為奇數3,5,7等等
- c:常量。從平均值或加權平均值中減去的常數,可能為正數、0或者負數
灰度化圖像
灰度圖像上每個像素的顏色值又稱為灰度,指黑白圖像中點的顏色深度,范圍一般從0到255,白色為255,黑色為0。所謂灰度值是指色彩的濃淡程度,灰度直方圖是指一幅數字圖像中,對應每一個灰度值統計出具有該灰度值的象素數。
圖像灰度化處理有以下幾種方式:
,
灰度化函數:
cvtColor(src, code, dst=None, dstCn=None)->gray_image
參數:
- src:源圖像,這里指的是opencv攝像頭讀取到的RGB圖像
- code:因為這里是要將RGB圖像轉換為Gray圖像,所有選擇的方法是cv2.COLOR_RGB2GRAY
- 其余為默認值即可。默認采取的灰度化方法是加權平均法
返回值:
- gray_image:返回的是灰度化的圖像。即三通道轉換為單通道
源代碼:
import cv2 import numpy as np """ 二值化進行圖像的背景分割: 1.全局閾值 2.局部閾值:表示自適應閾值算法,平均 (ADAPTIVE_THRESH_MEAN_C)或高斯(ADAPTIVE_THRESH_GAUSSIAN_C) 3.用戶自己計算閾值:中值法計算閾值 4.HSV閾值的計算 """def nothing(*arg):pass# 全局閾值 def threshold_demo(image, threshold_value):gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) # 把輸入圖像灰度化# 直接閾值化(對輸入的單通道矩陣逐像素進行閾值分割)表示的是二值化結合TRIANGLE法,全局自適應閾值,第二個參數值0可改為任意數字但不起作用,適用于單個波峰。ret, binary = cv2.threshold(gray, threshold_value, 255, cv2.THRESH_BINARY)print("threshold value %s" % ret)cv2.namedWindow("binary0", cv2.WINDOW_NORMAL)cv2.imshow("binary0", binary)# 局部閾值:表示自適應閾值算法,平均 (ADAPTIVE_THRESH_MEAN_C)或高斯(ADAPTIVE_THRESH_GAUSSIAN_C)。 def local_threshold(image):gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) # 把輸入圖像灰度化# 自適應閾值化能夠根據圖像不同區域亮度分布,改變閾值# 第三個參數必須為THRESH_BINARY或THRESH_BINARY_INV的閾值類型# 第四個參數blockSize參數表示塊大小(奇數且大于1,比如3,5,7........ )。# 最后一個參數是常數,表示從平均值或加權平均值中減去的數# 補充:在使用平均和高斯兩種算法情況下,通過計算每個像素周圍blockSize x blockSize大小像素塊的加權均值并減去常量C即可得到自適應閾值。如果使用平均的方法,則所有像素周圍的權值相同;如果使用高斯的方法,則每個像素周圍像素的權值則根據其到中心點的距離通過高斯方程得到。binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 25, 10)cv2.namedWindow("binary1", cv2.WINDOW_NORMAL)cv2.imshow("binary1", binary)# 用戶自己計算閾值:中值法計算閾值 def custom_threshold(image):gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) # 把輸入圖像灰度化h, w = gray.shape[:2]m = np.reshape(gray, [1, w * h])mean = m.sum() / (w * h)print("mean:", mean)ret, binary = cv2.threshold(gray, mean, 255, cv2.THRESH_BINARY)cv2.namedWindow("binary2", cv2.WINDOW_NORMAL)cv2.imshow("binary2", binary)# HSV閾值的調整,這里也可以通過HSV來對圖像閾值進行調整 def HSV():cap = cv2.VideoCapture(0)# set blue thresh 設置HSV中藍色、天藍色范圍lower_blue = np.array([78, 43, 46])upper_blue = np.array([110, 255, 255])while True:# get a frame and show 獲取視頻幀并轉成HSV格式, 利用cvtColor()將BGR格式轉成HSV格式,參數為cv2.COLOR_BGR2HSV。ret, frame = cap.read()cv2.imshow('Capture', frame)# change to hsv modelhsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)# get mask 利用inRange()函數和HSV模型中藍色范圍的上下界獲取mask,mask中原視頻中的藍色部分會被弄成白色,其他部分黑色。mask = cv2.inRange(hsv, lower_blue, upper_blue)cv2.imshow('Mask', mask)# detect blue 將mask于原視頻幀進行按位與操作,則會把mask中的白色用真實的圖像替換:res = cv2.bitwise_and(frame, frame, mask=mask)cv2.imshow('Result', res)if cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()cv2.destroyAllWindows()if __name__ == '__main__':cv2.namedWindow('colorThreshold')cv2.createTrackbar('threshold_value', 'colorThreshold', 0, 255, nothing)cap = cv2.VideoCapture(0)while True:ret, frame = cap.read()threshold_value = cv2.getTrackbarPos('threshold_value', 'colorThreshold')threshold_demo(frame, threshold_value)if cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()cv2.destroyAllWindows()效果:
調整的最終閾值:
分割出來的背景圖片:
總結
以上是生活随笔為你收集整理的python opencv二值化阈值图像分割的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 中文字体 推荐,适合阅读的中
- 下一篇: 在 Python 中使用网格搜索和随机搜