1. 程式人生 > 程式設計 >基於Python的影象閾值化分割(迭代法)

基於Python的影象閾值化分割(迭代法)

1.閾值化分割原理

通過對影象的灰度直方圖進行數學統計,選擇一個或多個閾值將畫素劃分為若干類。一般情況下,當影象由灰度值相差較大的目標和背景組成時,如果目標區域內部畫素灰度分佈均勻一致,背景區域畫素在另一個灰度級上也分佈均勻,這時影象的灰度直方圖會呈現出雙峰特性。

在這種情況下,選取位於這兩個峰值中間的谷底對應的灰度值T作為灰度閾值,將影象中各個畫素的灰度值與這個閾值進行比較,根據比較的結果將影象中的畫素劃分到兩個類中。畫素灰度值大於閾值T的畫素點歸為一類,其餘畫素點歸為另一類。經閾值化處理後的影象g(x,y)定義為:

在這裡插入圖片描述

其中f(x,y)為原影象,T為灰度閾值,g(x,y)為分割後產生的二值影象。

2.演算法流程圖

在這裡插入圖片描述

3.程式碼實現

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
#讀入圖片並轉化為矩陣
img = plt.imread('2.jpg')
im = np.array(img)

# 矩陣大小
l = len(im)
w = len(im[0])

#求初始閾值
zmin = np.min(im)
zmax = np.max(im)
t0 = int((zmin+zmax)/2)

#初始化相關變數初始化
t1=0
res1=0
res2=0
s1=0
s2=0

#迭代法計算最佳閾值
while abs(t0-t1)>0:
 for i in range(0,l-1):
  for j in range(0,w-1):
   if im[i,j]<t0:
    res1=res1+im[i,j]
    s1=s1+1
   elif im[i,j]>t0:
    res2=res2+im[i,j]
    s2=s2+1
 avg1=res1/s1
 avg2=res2/s2
 res1 = 0
 res2 = 0
 s1 = 0
 s2 = 0
 t1 = t0   #舊閾值儲存在t1中
 t0=int((avg1+avg2)/2)  #計算新閾值

#閾值化分割
#畫素點灰度值小於最佳閾值t0用0填充,其餘用255填充
im = np.where(im[...,:] < t0,255)

#繪製原圖視窗
plt.figure()
plt.imshow(img,cmap='gray')
plt.title('original')

#繪製原圖直方圖並顯示最佳閾值
plt.figure()
plt.hist(img.ravel(),256)
plt.title('hist')
plt.axvline(t0)  #繪製最佳閾值分割線
plt.text(25,6100,"Best Threshold:{}".format(t0),size = 15,alpha = 0.8)

#繪製閾值化分割後圖像
plt.figure()
plt.imshow(Image.fromarray(im),cmap='gray')
plt.title('new')

#繪製閾值化分割後圖像的直方圖
plt.figure()
plt.hist(im.ravel(),256)
plt.title('hist')

plt.show()

4.閾值化分割結果

原始影象

在這裡插入圖片描述

原始影象直方圖

在這裡插入圖片描述

閾值化分割後圖像

在這裡插入圖片描述

閾值化分割後圖像直方圖

在這裡插入圖片描述

到此這篇關於基於Python的影象閾值化分割(迭代法)的文章就介紹到這了,更多相關Python 影象閾值化分割內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!