前言
本文所涉是筆者模式識別課的第一次大做業——用樸素貝葉斯來作nemo魚圖像區域分割。它是用貝葉斯來作二元分類的簡單實踐,適合用來作貝葉斯算法入門,現將簡要理論和筆者所寫代碼放在這裏,供你們參考。不知道有沒有朋友有疑問,明明是圖像區域分割,怎麼又和二元分類扯上了關係,其實逐像素的圖像分割,就是在作分類。固然,這裏的分割不是指複雜的語義分割,只是簡單的根據灰度或者顏色分佈來作區域分割。python
貝葉斯理論:機器學習十大經典算法:深刻淺出聊貝葉斯決策git
任務與數據
圖像fish.bmp
與掩膜mask.mat
,掩膜點乘圖像,便可得到待分割區域ROI。小魚區域主要有兩種類型的區域,如下就是要用樸素貝葉斯把這兩個部分分出來——用不一樣的顏色表示不一樣區域。算法
訓練數據sample.mat
,它是一個二維的matlab數組,第一列爲灰度值,第2-4列爲RGB值,第五列爲當前灰度值或者RGB值對應的類別標籤(1,-1)。它蘊含着兩種類型區域的灰度值或者RGB值的分佈,根據它來估計兩種類型區域的類機率密度函數的參數。
數組
任務1:對訓練數據用極大似然,估計出兩類區域灰度值的機率密度函數,並用最小錯誤貝葉斯對fish.bmp
ROI灰度圖像進行分割。
任務2:對訓練數據用極大似然,估計出兩類區域RGB值的機率密度函數,並用最小錯誤貝葉斯對fish.bmp
ROI彩色圖像進行分割。
app
理論與實現
統計模型的訓練過程就是類條件機率密度函數參數的估計過程。經過參數估計方法,從訓練樣本中估計出參數,便完成了訓練。測試或者說應用過程就是用估計出的類機率密度函數和表明類別佔比的先驗機率進行統計決策或者分類的過程。最大似然是經常使用的參數估計方法,用在高斯混合模型(GMM)中。機器學習
假定咱們面對的就是一個高斯混合模型(GMM),即每一個類別訓練樣本的灰度值或者RGB值均服從正態分佈,正態分佈含有兩個參數,均值方差或者均值協方差。函數
咱們知道,極大似然的目的是要找到最可能產生該樣本序列的機率密度函數的參數。而在某機率密度函數參數下產生該樣本序列的機率如式(1),即似然函數。工具
當每一個樣本都獨立同分布(iid)時,對應的貝葉斯決策即爲樸素貝葉斯。則式(1)即可以化爲機率連乘的形式,如式(2),
兩邊同取天然對數後,用導數工具能夠求出其極大值點,即極大似然。在高斯混合模型的狀況下,某個樣本序列似然函數的極值點的解析解爲:
學習
一維狀況:對應灰度值。測試
多維狀況:三維時對應RGB值
由以上4個式子,咱們能夠看出。咱們習覺得然的求均值和方差的公式,實際上是在默認中央極限定理的前提下,用最大似然估計的結果。
copyright ©意疏:https://blog.csdn.net/sinat_35907936/article/details/109167111
由機器學習十大經典算法:深刻淺出聊貝葉斯決策,咱們能夠知道,在給類別地位均等時,採用最小錯誤率或者最大後驗機率貝葉斯決策便可。只比較分子,即下式,即可得出決策——選兩類中結果較大者爲決策結果。
算法流程以下圖所示,前半部分時統計模型的訓練過程,即用最大似然(MLE)進行參數估計。測試過程,就是用決策的過程,圖中爲爲Nemo魚逐像素作灰度或者顏色決策或者分割的過程。PDF爲scipy包中包含的正態分佈PDF函數,只需給其參數和輸入便可獲得輸出值。
數據加載與解析。python能夠經過scipy模塊讀取matlab文件。matlab文件讀入後是以字典的形式展示的。
from scipy import io from scipy.stats import norm import numpy as np import PIL.Image as Image import matplotlib.pyplot as plt from scipy.stats import multivariate_normal # 數據加載與解析 mask = io.loadmat('mask.mat')['Mask'] # 數據爲一個字典,根據key提取數據 sample = io.loadmat('sample.mat')['array_sample'] src_image = Image.open('fish.bmp') RGB_img = np.array(src_image) Gray_img = np.array(src_image.convert('L')) # 根據Mask,獲取ROI區域 Gray_ROI = (Gray_img * mask)/255 RGB_mask = np.array([mask, mask, mask]).transpose(1, 2, 0) RGB_ROI = (RGB_img * RGB_mask)/255 # 根據標籤拆分數據 gray1 = [] gray2 = [] RGB1 = [] RGB2 = [] for i in range(len(sample)): if(sample[i][4]) == 1.: # 數據第5位爲標籤 gray1.append(sample[i][0]) RGB1.append(sample[i][1:4]) else: gray2.append(sample[i][0]) RGB2.append(sample[i][1:4]) RGB1 = np.array(RGB1) RGB2 = np.array(RGB2)
計算先驗機率。先驗機率能夠經過樣本中各種別的佔比得來。也能夠經過各種別在世界中的佔比而來。
# 計算兩類在數據中的佔比,即先驗機率 P_pre1 = len(gray1)/len(sample) P_pre2 = 1-P_pre1
一維貝葉斯決策,計算一維輸入時貝葉斯後驗機率。
# 一維時,貝葉斯 # ------------------------------------------------------------------------------------# # 數據爲一維時(灰度圖像),用最大似然估計兩個類別條件機率pdf的參數——標準差與均值 gray1_m = np.mean(gray1) gray1_s = np.std(gray1) gray2_m = np.mean(gray2) gray2_s = np.std(gray2) # print(gray1_s, gray2_s) # 繪製最大似然估計出的類條件pdf x = np.arange(0, 1, 1/1000) gray1_pdf = norm.pdf(x, gray1_m, gray1_s) gray2_pdf = norm.pdf(x, gray2_m, gray2_s) plt.figure(0) ax = plt.subplot(2, 1, 1) ax.set_title('p(x|w)') ax.plot(x, gray1_pdf, 'r', x, gray2_pdf, 'b') ax.set_xlabel('x') ax.set_ylabel('f(x)') ax1 = plt.subplot(2, 1, 2) ax1.plot(x, P_pre1*gray1_pdf, 'r', x, P_pre2*gray2_pdf, 'b') ax1.set_title('p(w)*p(x|w)') ax1.set_xlabel('x') ax1.set_ylabel('f(x)') # 用最大後驗貝葉斯對灰度圖像進行分割 gray_out = np.zeros_like(Gray_img) for i in range(len(Gray_ROI)): for j in range(len(Gray_ROI[0])): if Gray_ROI[i][j] == 0: continue elif P_pre1*norm.pdf(Gray_ROI[i][j], gray1_m, gray1_s) > P_pre2*norm.pdf(Gray_ROI[i][j], gray2_m, gray2_s): # 貝葉斯公式分子比較 gray_out[i][j] = 100 else: gray_out[i][j] = 255 # plt.imshow(RGB_ROI) plt.figure(1) bx = plt.subplot(1, 1, 1) bx.set_title('gray ROI') bx.imshow(Gray_ROI, cmap='gray') plt.figure(2) bx1 = plt.subplot(1, 1, 1) bx1.set_title('gray segment result') bx1.imshow(gray_out, cmap='gray')
分割結果:
copyright ©意疏:https://blog.csdn.net/sinat_35907936/article/details/109167111
三維貝葉斯決策,計算三維輸入時的貝葉斯後驗機率。
# 三維時,貝葉斯 # ------------------------------------------------------------------------------------# # 數據爲三維時(彩色圖像),用最大似然估計兩個類別條件機率pdf的參數——協方差與均值 RGB1_m = np.mean(RGB1, axis=0) RGB2_m = np.mean(RGB2, axis=0) cov_sum1 = np.zeros((3, 3)) cov_sum2 = np.zeros((3, 3)) for i in range(len(RGB1)): # print((RGB1[i]-RGB1_m).reshape(3, 1)) cov_sum1 = cov_sum1 + np.dot((RGB1[i]-RGB1_m).reshape(3, 1), (RGB1[i]-RGB1_m).reshape(1, 3)) for i in range(len(RGB2)): cov_sum2 = cov_sum2 + np.dot((RGB2[i]-RGB2_m).reshape(3, 1), (RGB2[i]-RGB2_m).reshape(1, 3)) RGB1_cov = cov_sum1/(len(RGB1)-1) # 無偏估計除以N-1 RGB2_cov = cov_sum2/(len(RGB2)-1) xx = np.array([x, x, x]) # print(P_pre1*multivariate_normal.pdf(RGB1, RGB1_m, RGB1_cov)) # 用最大後驗貝葉斯對彩色圖像進行分割 RGB_out = np.zeros_like(RGB_ROI) for i in range(len(RGB_ROI)): for j in range(len(RGB_ROI[0])): if np.sum(RGB_ROI[i][j]) == 0: continue elif P_pre1*multivariate_normal.pdf(RGB_ROI[i][j], RGB1_m, RGB1_cov) > P_pre2*multivariate_normal.pdf(RGB_ROI[i][j], RGB2_m, RGB2_cov): # 貝葉斯公式分子比較 RGB_out[i][j] = [255, 0, 0] else: RGB_out[i][j] = [0, 255, 0] # print(RGB_ROI.shape) # 顯示RGB ROI,與彩色分割結果 plt.figure(3) cx = plt.subplot(1, 1, 1) cx.set_title('RGB ROI') cx.imshow(RGB_ROI) plt.figure(4) cx1 = plt.subplot(1, 1, 1) cx1.set_title('RGB segment result') cx1.imshow(RGB_out) plt.show()
分割結果:
copyright ©意疏:https://blog.csdn.net/sinat_35907936/article/details/109167111
參考
張學工.模式識別(第三版).M.清華大學出版社.2010.