The theory is introduced :
Click here to
import random
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus']=False
from sklearn import datasets
m=2
class FCM:
def __init__(self, data, clust_num,iter_num=10):
self.data = data
self.cnum = clust_num
self.sample_num=data.shape[0]
self.dim = data.shape[-1] # Last dimension of data
Jlist=[] # A matrix that stores the calculated values of the objective function
U = self.Initial_U(self.sample_num, self.cnum)
for i in range(0, iter_num): # The number of iterations is... By default 10
C = self.Cen_Iter(self.data, U, self.cnum)
U = self.U_Iter(U, C)
print(" The first %d Sub iteration " %(i+1) ,end="")
print(" Cluster center ",C)
J = self.J_calcu(self.data, U, C) # Calculate the objective function
Jlist = np.append(Jlist, J)
self.label = np.argmax(U, axis=0) # Classification labels for all samples
self.Clast = C # The last class center matrix
self.Jlist = Jlist # A matrix that stores the calculated values of the objective function
# Initialize the membership matrix U
def Initial_U(self, sample_num, cluster_n):
U = np.random.rand(sample_num, cluster_n) # sample_num Is the number of samples , cluster_n Is the number of categories
row_sum = np.sum(U, axis=1) # Sum up by line row_sum: sample_num*1
row_sum = 1 / row_sum # Each number of the matrix takes the reciprocal
U = np.multiply(U.T, row_sum) # Make sure U The sum of each column of is 1 (cluster_n*sample_num).*(sample_num*1)
return U # cluster_n*sample_num
# Computing Center
def Cen_Iter(self, data, U, cluster_n):
c_new = np.empty(shape=[0, self.dim]) # self.dim Is the last dimension of the sample matrix
for i in range(0, cluster_n): # As scattered dim by 2, Pixel value of the picture dim by 1
u_ij_m = U[i, :] ** m # (sample_num,)
sum_u = np.sum(u_ij_m)
ux = np.dot(u_ij_m, data) # (dim,)
ux = np.reshape(ux, (1, self.dim)) # (1,dim)
c_new = np.append(c_new, ux / sum_u, axis=0) # Add the class center to the class center matrix in the direction of the column
return c_new # cluster_num*dim
# Membership matrix iteration
def U_Iter(self, U, c):
for i in range(0, self.cnum):
for j in range(0, self.sample_num):
sum = 0
for k in range(0, self.cnum):
temp = (np.linalg.norm(self.data[j, :] - c[i, :]) /
np.linalg.norm(self.data[j, :] - c[k, :])) ** (
2 / (m - 1))
sum = temp + sum
U[i, j] = 1 / sum
return U
# Calculate objective function value
def J_calcu(self, data, U, c):
temp1 = np.zeros(U.shape)
for i in range(0, U.shape[0]):
for j in range(0, U.shape[1]):
temp1[i, j] = (np.linalg.norm(data[j, :] - c[i, :])) ** 2 * U[i, j] ** m
J = np.sum(np.sum(temp1))
print(" The value of the objective function :%.2f" %J)
return J
# Print the clustering result graph
def plot(self):
mark = ['or', 'ob', 'og', 'om', 'oy', 'oc'] # Color and shape of cluster points
if self.dim == 2:
# The first picture
plt.subplot(221)
plt.plot(self.data[:, 0], self.data[:, 1],'ob',markersize=2)
plt.title(' Scatter before clustering ')
# The second picture
plt.subplot(222)
j = 0
for i in self.label:
plt.plot(self.data[j:j + 1, 0], self.data[j:j + 1, 1], mark[i],
markersize=2)
j += 1
plt.plot(self.Clast[:, 0], self.Clast[:, 1], 'k*', markersize=7)
plt.title(" The result after clustering ")
# The third picture
plt.subplot(212)
plt.plot(self.Jlist, 'g-', )
plt.title(" Objective function change diagram ",)
plt.show()
elif self.dim==1:
plt.subplot(221)
plt.title(" Scatter before clustering ")
for j in range(0, self.data.shape[0]):
plt.plot(self.data[j, 0], 'ob',markersize=3) # Print a scatter plot
plt.subplot(222)
j = 0
for i in self.label:
plt.plot(self.data[j:j + 1, 0], mark[i], markersize=3)
j += 1
plt.plot([0]*self.Clast.shape[0],self.Clast[:, 0], 'k*',label=' Cluster center ',zorder=2)
plt.title(" Result graph after clustering ")
plt.legend()
# The third picture
plt.subplot(212)
plt.plot(self.Jlist, 'g-', )
plt.title(" Objective function change diagram ", )
plt.show()
elif self.dim==3:
# The first picture
fig = plt.figure()
ax1 = fig.add_subplot(221, projection='3d')
ax1.scatter(self.data[:, 0], self.data[:, 1],self.data[:,2], "b")
ax1.set_xlabel("X Axis ")
ax1.set_ylabel("Y Axis ")
ax1.set_zlabel("Z Axis ")
plt.title(" Graph before clustering ")
# The second picture
ax2 = fig.add_subplot(222, projection='3d')
j = 0
for i in self.label:
ax2.plot(self.data[j:j+1, 0], self.data[j:j+1, 1],self.data[j:j+1,2], mark[i],markersize=5)
j += 1
ax2.plot(self.Clast[:, 0], self.Clast[:, 1], self.Clast[:, 2], 'k*', label=' Cluster center ', markersize=8)
plt.legend()
ax2.set_xlabel("X Axis ")
ax2.set_ylabel("Y Axis ")
ax2.set_zlabel("Z Axis ")
plt.title(" The result after clustering ")
# # The third picture
plt.subplot(212)
plt.plot(self.Jlist, 'g-', )
plt.title(" Objective function change diagram ", )
plt.show()
def example0():
N=1000
C=[[N/4,N/2,0,N/2],[N/2,N,0,N/2],[N/4,N/2,N/2,N],[N/2,N,N/2,N]]
data=[]
for i in range(4):
center_datanum=random.randint(20,50)
for j in range(center_datanum):
change=random.randint(20,100)
x=random.randint(C[i][0]+change,C[i][1]-change)
y=random.randint(C[i][2]+change,C[i][3]-change)
data.append([x,y])
data=np.mat(data)
a=FCM(data,4,20)
a.plot()
def example1():
x1 = np.zeros((10, 1))
x2 = np.zeros((10, 1))
for i in range(0, 10):
x1[i] = np.random.rand() * 5
x2[i] = np.random.rand() * 5 + 5
x = np.append(x1, x2, axis=0)
a = FCM(x, 2,20)
a.plot()
def example2():
x1 = np.zeros((10, 1))
y1 = np.zeros((10, 1))
x2 = np.zeros((10, 1))
y2 = np.zeros((10, 1))
x3 = np.zeros((10, 1))
y3 = np.zeros((10, 1))
for i in range(0, 10):
x1[i] = np.random.rand() * 5
y1[i] = np.random.rand() * 5
x2[i] = np.random.rand() * 5 + 5
y2[i] = np.random.rand() * 5 + 5
x3[i] = np.random.rand() * 0.5 + 1
y3[i] = np.random.rand() * 0.5 + 1
x = np.append(x1, x2, axis=0)
x = np.append(x, x3, axis=0)
y = np.append(y1, y2, axis=0)
y = np.append(y, y3, axis=0)
data = np.append(x, y, axis=1)
a = FCM(data, 3,20) # Divide the data into three categories
a.plot() # Print the result map
def example3():
x1 = np.zeros((10, 1))
y1 = np.zeros((10, 1))
z1= np.zeros((10, 1))
x2 = np.zeros((10, 1))
y2 = np.zeros((10, 1))
z2 = np.zeros((10, 1))
x3 = np.zeros((10, 1))
y3 = np.zeros((10, 1))
z3 = np.zeros((10, 1))
for i in range(0, 10):
x1[i] = np.random.rand() * 5
y1[i] = np.random.rand() * 5
z3[i] = np.random.rand() * 5
x2[i] = np.random.rand() * 5 + 5
y2[i] = np.random.rand() * 5 + 5
z2[i] = np.random.rand() * 5+5
x3[i] = np.random.rand() * 0.5 + 1
y3[i] = np.random.rand() * 0.5 + 1
z3[i] = np.random.rand() * 0.5 + 3
x = np.append(x1, x2, axis=0)
x = np.append(x, x3, axis=0)
y = np.append(y1, y2, axis=0)
y = np.append(y, y3, axis=0)
z = np.append(z1, z2, axis=0)
z = np.append(z, z3, axis=0)
data = np.append(x, y, axis=1)
print(data.shape)
data=np.append(data,z,axis=1)
a = FCM(data, 3,20) # Divide the data into three categories
a.plot() # Print the result map
if __name__ == '__main__':
example0()
#example1()
#example2()
#example3()
import matplotlib.pyplot as plt
import cv2
from FCMTEST import FCM
import numpy as np
def FCM_pic_cut0(img_path,gray=False,clustercenternum=5,iternum=10):
if gray:
img=cv2.imread(img_path,0) # grayscale
data=img.reshape(img.shape[0]*img.shape[1],1) # Pull the pictures into a column
else:
img=cv2.imread(img_path)
img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB) # Turn into RGB, Otherwise plt The picture will be strange
data=img.reshape(-1,3) # Reduce 3D to 2D
print(" Start clustering ")
test=FCM(data,clustercenternum,iternum)
cluster=test.label # Clustering results
center=test.Clast # Cluster center
print(" Clustering complete , Start generating pictures ")
new_img=center[cluster] # A new image is constructed according to the clustering results and clustering centers
new_img=np.reshape(new_img,img.shape) # The matrix is transformed into the shape of the original picture
new_img=new_img.astype('uint8') # To become an image, the data has to be converted into uint8
if gray:
plt.subplot(121), plt.imshow(img, cmap="gray"), plt.title(" Original picture ") # plt Three channels are displayed by default , The grayscale image should be added with cmap="gray", Otherwise the picture is green ..
plt.subplot(122), plt.imshow(new_img, cmap="gray"), plt.title("FCM,%d Cluster centers "%clustercenternum)
else :
plt.subplot(121), plt.imshow(img), plt.title(" Original picture ")
plt.subplot(122), plt.imshow(new_img), plt.title("FCM,%d Cluster centers "%clustercenternum)
plt.show()
#plt.imsave("cutgray.jpg",new_img) # Save the picture
if __name__ == '__main__':
FCM_pic_cut0("Mai_sakurajima.jpg",gray=False,clustercenternum=15)