首頁 > 軟體

Python+OpenCV實現閾值分割的方法詳解

2022-05-16 16:00:10

一、全域性閾值

原圖:

整幅圖採用一個閾值,與圖片的每一個畫素灰度進行比較,重新賦值;

1.效果圖

2.原始碼

import cv2
import matplotlib.pyplot as plt
#設定閾值
thresh=130
#載入原圖,並轉化為灰度影象
img_original=cv2.imread(r'E:pypython3.7test2test14yuzhicell.png',0)
img_original=cv2.resize(img_original,(0,0),fx=0.3,fy=0.3)
#採用5種閾值型別(thresholding type)分割影象
retval1,img_binary=cv2.threshold(img_original,thresh,255,cv2.THRESH_BINARY)
retval2,img_binary_invertion=cv2.threshold(img_original,thresh,255,cv2.THRESH_BINARY_INV)
retval3,img_trunc=cv2.threshold(img_original,thresh,255,cv2.THRESH_TRUNC)
retval4,img_tozero=cv2.threshold(img_original,thresh,255,cv2.THRESH_TOZERO)
retval5,img_tozero_inversion=cv2.threshold(img_original,thresh,255,cv2.THRESH_TOZERO_INV)
#採用plt.imshow()顯示影象
imgs=[img_original,img_binary,img_binary_invertion,img_trunc,img_tozero,img_tozero_inversion]
titles=['original','binary','binary_inv','trunc','tozero','tozero_inv']
for i in range(6):
    plt.subplot(2,3,i+1)
    plt.imshow(imgs[i],'gray')
    plt.title(titles[i])
    plt.xticks([])
    plt.yticks([])
plt.show()

二、滑動改變閾值(滑動條)

1.效果圖

2.原始碼

程式碼如下(範例):

import cv2
import numpy as np
import matplotlib.pyplot as plt
#載入原圖,轉化為灰度影象,並通過cv2.resize()等比調整影象大小
img_original=cv2.imread(r'E:pypython3.7test2test14yuzhicell.png',0)
img_original=cv2.resize(img_original,(0,0),fx=0.3,fy=0.3)
#初始化閾值,定義全域性變數imgs
thresh=130
imgs=0
#建立滑動條回撥函數,引數thresh為滑動條對應位置的數值
def threshold_segmentation(thresh):
    #採用5種閾值型別(thresholding type)分割影象
    retval1,img_binary=cv2.threshold(img_original,thresh,255,cv2.THRESH_BINARY)
    retval2,img_binary_invertion=cv2.threshold(img_original,thresh,255,cv2.THRESH_BINARY_INV)
    retval3,img_trunc=cv2.threshold(img_original,thresh,255,cv2.THRESH_TRUNC)
    retval4,img_tozero=cv2.threshold(img_original,thresh,255,cv2.THRESH_TOZERO)
    retval5,img_tozero_inversion=cv2.threshold(img_original,thresh,255,cv2.THRESH_TOZERO_INV)
    #由於cv2.imshow()顯示的是多維陣列(ndarray),因此我們通過np.hstack(陣列水平拼接)
    #和np.vstack(豎直拼接)拼接陣列,達到同時顯示多幅圖的目的
    img1=np.hstack([img_original,img_binary,img_binary_invertion])
    img2=np.hstack([img_trunc,img_tozero,img_tozero_inversion])
    global imgs
    imgs=np.vstack([img1,img2])
#新建視窗
cv2.namedWindow('Images')
#新建滑動條,初始位置為130
cv2.createTrackbar('threshold value','Images',130,255,threshold_segmentation)
#第一次呼叫函數
threshold_segmentation(thresh)
#顯示影象
while(1):
    cv2.imshow('Images',imgs)
    if cv2.waitKey(1)==ord('q'):
        break
cv2.destroyAllWindows()

三、自適應閾值分割

1.效果圖

2.原始碼

程式碼如下(範例):

import cv2
import matplotlib.pyplot as plt
#載入原圖
img_original=cv2.imread(r'E:pypython3.7test2test14yuzhicell.png',0)
#全域性閾值分割
retval,img_global=cv2.threshold(img_original,130,255,cv2.THRESH_BINARY)
#自適應閾值分割
img_ada_mean=cv2.adaptiveThreshold(img_original,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,15,3)
img_ada_gaussian=cv2.adaptiveThreshold(img_original,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,15,3)
imgs=[img_original,img_global,img_ada_mean,img_ada_gaussian]
titles=['Original Image','Global Thresholding(130)','Adaptive Mean','Adaptive Guassian',]
#顯示圖片
for i in range(4):
    plt.subplot(2,2,i+1)
    plt.imshow(imgs[i],'gray')
    plt.title(titles[i])
    plt.xticks([])
    plt.yticks([])
plt.show()

3.GaussianBlur()函數去噪

程式碼如下(範例):

import cv2
import matplotlib.pyplot as plt
#載入原圖
img_original=cv2.imread(r'E:pypython3.7test2test14yuzhicell.png',0)
#高斯濾波
img_blur=cv2.GaussianBlur(img_original,(13,13),13)  #根據情況修改引數
#自適應閾值分割
img_thresh=cv2.adaptiveThreshold(img_original,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,15,3)
img_thresh_blur=cv2.adaptiveThreshold(img_blur,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,15,3)
#顯示影象
imgs=[img_thresh,img_thresh_blur]
titles=['img_thresh','img_thresh_blur']
for i in range(2):
    plt.subplot(1,2,i+1)
    plt.imshow(imgs[i],'gray')
    plt.title(titles[i])
    plt.xticks([])
    plt.yticks([])
plt.show()

四、引數解釋

1.cv2.threshold(src, thresh, maxval, type)

引數:

src:輸入的影象

thresh:影象分割所用的閾值(threshold value)

maxval:當閾值型別(thresholding type)採用cv2.THRESH_BINARY和cv2.THRESH_BINARY_INV時畫素點被賦予的新值

type:介紹6種型別:

cv2.THRESH_BINARY(當影象某點畫素值大於thresh(閾值)時賦予maxval,反之為0。注:最常用)

cv2.THRESH_BINARY_INV(當影象某點畫素值小於thresh時賦予maxval,反之為0)

cv2.THRESH_TRUNC(當影象某點畫素值大於thresh時賦予thresh,反之不變。注:雖然maxval沒用了,但是呼叫函數不能省略)

cv2.THRESH_TOZERO(當影象某點畫素值小於thresh時賦予0,反之不變。注:同上)

cv2.THRESH_TOZERO_INV(當影象某點畫素值大於thresh時賦予0,反之不變。注:同上)

cv2.THRESH_OTSU(該方法自動尋找最優閾值,並返回給retval,見下文)

返回值:

retval:設定的thresh值,或者是通過cv2.THRESH_OTSU算出的最優閾值

dst:閾值分割後的影象

以上就是Python+OpenCV實現閾值分割的方法詳解的詳細內容,更多關於Python OpenCV閾值分割的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com