MRF MRF entry
Intro
MRF is not a widely used model for image segmentation, of course, because when I saw the MRF division, but in the field of image generation, and some paper using the MRF model to generate an image, so what MRF entry, and to divide the model for example remember the code.
Model
Target
In image segmentation, our task is given a picture, and output label of each pixel. So we just want to get in a given picture features under the label corresponding to maximize the probability of tag.
Can be so modeled:
\ [\ Hat {\ Omega} = Arg \ max _ {\ Omega \ in \ Omega} P (\ Omega | F) \]
where w represents the tag, f denotes image features, seeking the maximum posterior probability .
Bayesian theory, right-hand side can be written as:
\ [P (\ Omega | F) = \ {FRAC P (F | \ Omega) P (\ Omega)} {P (F)} \]
where, P ( f) is constant, because when a picture is determined, P (f) will be determined. Thus, the equation depends only on molecular moiety.
Therefore, our task only needs to be defined for the two parts of the molecule.
Neighbors
Neighbors pixel definition is simply that other pixels around this pixel.
For example, the center point of the pixel of FIG respectively eight neighbors and neighbor domain.
Hammersley-Clifford Theorem
Hammersley-Clifford Theorem show CRFs where p (w) must satisfy the Gibbs distribution, so defined by the following formula:
\ [P (\ Omega) = \ FRAC the Z {} {}. 1 exp (-U ( \ omega)) = \ frac {
1} {Z} exp (- \ sum_ {c \ in C} V_c (\ omega)) \] wherein, Z as a normalization term, \ (the Z = exp (-U (\ Omega )) \) , defined as the potential energy U, while the far right of the equal sign will become a sum U V, and later we will talk, in fact, here is the potential energy of each atom group sum.
Click
Clique is the concept of "group" we mentioned above. Set \ (c \) is \ (S \) atomic group c if and only if each element is adjacent to the other elements of the set. So Clique's all \ (c \) and set.
\ [C = c_1 \ cup c_2 \ cdots c_n \]
For example:
A pixel neighbors and his own domain consisting of radicals can be divided into a set of singleton and doubleton shown in FIG.
Clique Potential
Translation is the potential energy, with \ (V (w) \) indicated that describes a Clique energy.
Then, a pixel area of the potential energy is the energy of each group and.
\ [U (\ omega) =
\ sum_ {c \ in C} V_c (w) \] wherein c represents an atomic group, c denotes Clique, V is how to define it?
In image segmentation, an example may be a first order group,
\ [V_c (\ Omega) = \ Beta \ Delta (W, w_s) = \ left \ {\ the aligned the begin {} \ \\ w_s Beta && W = - \ Beta && w \ neq w_s \\\ end {
aligned} \ right \]. here, \ (P (\ Omega) \) all variables explained over, the next step is to calculate the \ (P (f | \ omega ) \)
(P (f | \ omega) \) \ calculated
\ (P (f | \ omega ) \) is a Gaussian distribution, that is, if we know what label this pixel, then the pixel values should obey his conditional probability under the label of a Gaussian distribution.
\ [P (f_s | \ omega_s ) = \ frac {1} {\ sqrt {2 \ pi} \ sigma_ {w_s}} exp (- \ frac {(f_s - \ mu _ {\ omega_s}) ^ 2} {2 \ sigma ^ 2 _ {\ omega_s
}}) \] calculated for each category mean and variance of the pixel, into the formula, to obtain the conditional probability.
Finally, is to maximize \ (P (\ Omega) P (f | \ Omega) \) , in logarithmic form into the form of sum to optimize, maximize \ (log (P (\ omega )) + log ( P (f | \ Omega)) \) .
Coding
import numpy as np
import cv2 as cv
import copy
class MRF():
def __init__(self,img,max_iter = 100,num_clusters = 5,init_func = None,beta = 10):
self.max_iter = max_iter
self.kernels = np.zeros(shape = (8,3,3))
self.beta = beta
self.num_clusters = num_clusters
for i in range(9):
if i < 4:
self.kernels[i,i//3,i%3] = 1
elif i > 4:
self.kernels[i-1,(i-1)//3,(i-1)%3] = 1
self.img = img
if init_func is None:
self.labels = np.random.randint(low = 1,high = num_clusters + 1,size = img.shape,dtype = np.uint8)
def __call__(self):
#print(self.labels)
#print(self.img)
img = self.img.reshape((-1,))
for iter in range(self.max_iter):
p1 = np.zeros(shape = (self.num_clusters,self.img.shape[0] * self.img.shape[1]))
for cluster_idx in range(self.num_clusters):
temp = np.zeros(shape = (self.img.shape))
for i in range(8):
res = cv.filter2D(self.labels,-1,self.kernels[i,:,:])
temp[(res == (cluster_idx + 1))] += self.beta
temp[(res == (cluster_idx + 1))] -= self.beta
#temp += (res == (cluster_idx + 1)).astype(np.int)
temp = np.exp(-temp)
#temp = temp/8.0
p1[cluster_idx,:] = temp.reshape((-1,))
p1 = p1 / np.sum(p1,axis = 0)
p1[p1 == 0] = 1e-3
mu = np.zeros(shape = (self.num_clusters,))
sigma = np.zeros(shape = (self.num_clusters,))
for i in range(self.num_clusters):
#mu[i] = np.mean(self.img[self.labels == (i+1)])
data = self.img[self.labels == (i+1)]
if np.sum(data) > 0:
mu[i] = np.mean(data)
sigma[i] = np.var(data)
else:
mean = 0
sigma[i] = 1
#print(sigma[i])
#sigma[sigma == 0] = 1e-3
p2 = np.zeros(shape = (self.num_clusters,self.img.shape[0] * self.img.shape[1]))
for i in range(self.img.shape[0] * self.img.shape[1]):
for j in range(self.num_clusters):
#print(sigma[j])
p2[j,i] = -np.log(np.sqrt(2*np.pi)*sigma[j]) -(img[i]-mu[j])**2/2/sigma[j];
self.labels = np.argmax(np.log(p1) + p2,axis = 0) + 1
self.labels = np.reshape(self.labels,self.img.shape).astype(np.uint8)
print("-----------start-----------")
print(p1)
print("-" * 20)
print(p2)
print("----------end------------")
#print("iter {} over!".format(iter))
#self.show()
#print(self.labels)
def show(self):
img = copy.copy(self.labels)
img[img == 1] = 0
img[img == 2] = 80
img[img == 3] = 160
img[img == 4] = 240
#img = self.labels / (self.num_clusters) * 255
cv.imshow("res",img.astype(np.uint8))
cv.waitKey(0)
if __name__ == "__main__":
img = cv.imread("/home/xueaoru/图片/test002.jpg")
img = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
img = img/255.
#img = np.random.rand(64,64)
#img = cv.resize(img,(256,256))
mrf = MRF(img = img,max_iter = 20,num_clusters = 2)
mrf()
mrf.show()
#print(mrf.kernels)
Input:
Output(num_clusters = 4):
Output(num_clusters = 2):