程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

python opencv二值化阈值圖像分割

編輯:Python

在一般的視覺視覺顏色是由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

    1. 反二進制阈值化THRESH_BINARY_INV

    3)截斷阈值化 THRESH_TRUNC

    1. 阈值化為0 THRESH_TOZERO

    2. 反阈值化為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相同大小和類型以及相同通道數的數組/圖像)

返回值:

  • 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。所謂灰度值是指色彩的濃淡程度,灰度直方圖是指一幅數字圖像中,對應每一個灰度值統計出具有該灰度值的象素數。
圖像灰度化處理有以下幾種方式:

  1. 分量法:彩色圖像中的三分量的亮度作為三個灰度圖像的灰度值,可根據應用需要選取一種灰度圖像
  2. 最大值法:將彩色圖像中的三分量亮度的最大值作為灰度圖的灰度值。
  3. 平均值法:將彩色圖像中的三分量亮度求平均得到一個灰度值。
  4. 加權平均法:根據重要性及其它指標,將三個分量以不同的權值進行加權平均。由於人眼對綠色的敏感最高,對藍色敏感最低,因此,按下式對RGB三分量進行加權平均能得到較合理的灰度圖像。
    ,
    灰度化函數:
    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 model
hsv = 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'):
break
cap.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'):
break
cap.release()
cv2.destroyAllWindows()

效果:
調整的最終阈值:

分割出來的背景圖片:


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved