[Study notes] MRF entry

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):

Guess you like

Origin www.cnblogs.com/aoru45/p/12079722.html