前言
之前處理圖像二值化時(shí)使用的是經(jīng)典的Otsu算法,這次要求使用Fuzzy Density Model去做一個(gè)圖像二值化處理,網(wǎng)上參考文檔除了作者的論文,幾乎為零,可參考代碼都沒(méi)有。所以讀完論文后特地記錄一下。
先聲明:這篇論文還沒(méi)有完全理解吸收,記錄自己學(xué)習(xí)過(guò)程,如果有誤,歡迎交流
論文簡(jiǎn)介
一般圖像二值化的處理是對(duì)圖像灰度化后,處理其直方圖,取其中的一個(gè)點(diǎn)作為threshold,以此為界,將圖片中灰度小于該點(diǎn)的值、大于該點(diǎn)的值分成兩部分。
Fuzzy Set Theory
作者先介紹了一個(gè)稱作Fuzzy Set的理論。令X={X1,X2....Xn},函數(shù)μ,它將X中的每個(gè)元素映射到[0,1]區(qū)間上,即對(duì)于X中元素Xi,有: 0<=μ(Xi)<=1,令A(yù)={( Xi , μ(Xi) )},A即為X上的Fuzzy Set。相當(dāng)于對(duì)于X中的每個(gè)元素給予了一個(gè)0-1的權(quán)重。這里的μ特別地被稱為membership function。
Fuzzy Set Model
何為圖像密度?以下圖為例,假設(shè)點(diǎn)距離圓心越近,則擁有越高的權(quán)重,那么我們可以得出(a)圖中點(diǎn)權(quán)重之和比上以r為半徑的圓面積,大于,(b)圖中點(diǎn)權(quán)重之后比上以r為半徑的圓面積

論文里提到了三個(gè)membership function,分別為
-
Zadeh’s S-membership function
-
Gamma membership function
-
Gaussian membership function
這里引入fdm(r,p)函數(shù),用于計(jì)算fuzzy density,r為計(jì)算的圖像區(qū)域,p為區(qū)域內(nèi)的點(diǎn)。fdm計(jì)算結(jié)果越高,則相似度越大。
Threshold Selection Method
對(duì)于圖像的直方圖有明、暗兩部分,對(duì)于Object(亮部),顯然有灰度越小,越暗,權(quán)重越低,對(duì)于Background則反之,所以如果我們分別選取灰度圖中最大、最小作為明暗中心,做出他們的fdm函數(shù),大致如圖

交界處即為所需要的threshold。
The Rest
論文剩余部分對(duì)左右兩個(gè)初始區(qū)域、以及threshold的適當(dāng)調(diào)整做了更近一步探討,這里暫時(shí)不記錄了(主要是沒(méi)有看大明白。。。),有興趣讀者可以查看作者原論文
實(shí)踐
Lang:Python
Package:PIL
# Created by william wei on 17/1/7.
# Copyright ? 2017年. All rights reserved.
import PIL
import math
from PIL import Image
Xmin=0
Xmax=0
hist = []
def membership_function(x):
b = (Xmin+Xmax)/2
x = x*1.0
if x <= Xmin:
return 0
if x>Xmin and x<=b:
return 2*math.pow( (x-Xmin)/(Xmax-Xmin), 2 )
if x>b and x<Xmax:
return 1-2*math.pow( (x-Xmax)/(Xmax-Xmin), 2 )
if x>=Xmax:
return 1
return 0
def fdm(x,y,inverse=0):
global Xmin,Xmax
result = 0
num = 0
for i in xrange(x,y):
num = num+hist[i]
if inverse==1:
result = result+hist[i]*membership_function(Xmax-(i-Xmin))
else:
result = result+hist[i]*(membership_function(i))
return result/num
if __name__ == "__main__":
im=Image.open('cherry.png')
im = im.convert('L')
hist = im.histogram()
threshold = 0
for i in xrange(0,256):
if hist[i] > 0:
Xmin = i
break;
for i in xrange(0,256):
if hist[255-i] > 0:
Xmax = 255-i
break;
for x in xrange(Xmin+1,Xmax):
left = fdm(Xmin,x,1)
right = fdm(x,Xmax)
if left<right and threshold == 0:
threshold = x
print threshold
height,width = im.size
bkg = im.convert('L')
obj = im.convert('L')
for x in xrange(0,height):
for y in xrange(0,width):
pixel = im.getpixel((x,y))
print (threshold)
if pixel<threshold :
obj.putpixel((x,y),0)
else:
bkg.putpixel((x,y),0)
bkg.save('bkg.png')
obj.save('obj.png')
效果如圖:
-
原圖
-
Object
-
Background
再說(shuō)點(diǎn)
效果說(shuō)實(shí)話,確實(shí)不是很好,比Otsu差不少,不過(guò)這倒不是作者的問(wèn)題,應(yīng)該是把論文剩余部分讀完的原因吧,姑且先這樣,后面有時(shí)間再回來(lái)研究一下。





