基于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, 0, 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.閾值化分割結果
原始影像

原始影像直方圖

閾值化分割后影像

閾值化分割后影像直方圖

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/225360.html
標籤:python
上一篇:Python練習:讀寫CSV檔案
