python图像分割算法_FCM算法图像分割python

import cv2

import numpy as np

C = 2

M = 2

EPSILON = 0.001

def get_init_fuzzy_mat(pixel_count):

global C

fuzzy_mat = np.zeros((C, pixel_count))

for col in range(pixel_count):

temp_sum = 0

randoms = np.random.rand(C - 1, 1)

for row in range(C - 1):

fuzzy_mat[row, col] = randoms[row, 0] * (1 - temp_sum)

temp_sum += fuzzy_mat[row, col]

fuzzy_mat[-1, col] = 1 - temp_sum

return fuzzy_mat

def get_centroids(data_array, fuzzy_mat):

global M

class_num, pixel_count = fuzzy_mat.shape[:2]

centroids = np.zeros((class_num, 1))

for i in range(class_num):

fenzi = 0.

fenmu = 0.

for pixel in range(pixel_count):

fenzi += np.power(fuzzy_mat[i, pixel], M) * data_array[0, pixel]

fenmu += np.power(fuzzy_mat[i, pixel], M)

centroids[i,0] = fenzi / fenmu

return centroids

def eculidDistance(vectA, vectB):

return np.sqrt(np.sum(np.power(vectA - vectB, 2)))

def eculid_distance(pixel_1, pixel_2):

return np.power(pixel_1-pixel_2, 2)

def cal_fcm_function(fuzzy_mat, centroids, data_array):

global M

class_num, pixel_count = fuzzy_mat.shape[:2]

target_value = 0.0

for c in range(class_num):

for p in range(pixel_count):

target_value += eculid_distance(data_array[0,p], centroids[c,0])*np.power(fuzzy_mat[c,p], M)

return target_value

def get_label(fuzzy_mat, data_array):

pixel_count = data_array.shape[1]

label = np.zeros((1,pixel_count))

for i in range(pixel_count):

if fuzzy_mat[0,i] > fuzzy_mat[1,i]:

label[0,i] = 0

else:

label[0,i] = 255

return label

def cal_fuzzy_mat(data_array, centroids):

global M

pixel_count = data_array.shape[1]

class_num = centroids.shape[0]

new_fuzzy_mat = np.zeros((class_num, pixel_count))

for p in range(pixel_count):

for c in range(class_num):

temp_sum = 0.

Dik = eculid_distance(data_array[0,p], centroids[c,0])

for i in range(class_num):

temp_sum += np.power(Dik/(eculid_distance(data_array[0,p], centroids[i,0])), (1/(M-1)))

new_fuzzy_mat[c,p] = 1/temp_sum

return new_fuzzy_mat

def fcm(init_fuzzy_mat, init_centroids, data_array):

global EPSILON

last_target_function = cal_fcm_function(init_fuzzy_mat, init_centroids, data_array)

print("迭代次数 = 1, 目标函数值 = {}".format(last_target_function))

fuzzy_mat = cal_fuzzy_mat(data_array, init_centroids)

centroids = get_centroids(data_array, fuzzy_mat)

target_function = cal_fcm_function(fuzzy_mat, centroids, data_array)

print("迭代次数 = 2, 目标函数值 = {}".format(target_function))

count = 3

while count < 100:

if abs(target_function-last_target_function) <= EPSILON:

break

else:

last_target_function = target_function

fuzzy_mat = cal_fuzzy_mat(data_array, centroids)

centroids = get_centroids(data_array, fuzzy_mat)

target_function = cal_fcm_function(fuzzy_mat, centroids, data_array)

print("迭代次数 = {}, 目标函数值 = {}".format(count, target_function))

count += 1

return fuzzy_mat, centroids, target_function

image = cv2.imread(r"C:\Users\Desktop\test.jpg", cv2.IMREAD_GRAYSCALE)

rows, cols = image.shape[:2]

pixel_count = rows * cols

image_array = image.reshape(1, pixel_count)

# print(image_array[1])

# 初始模糊矩阵

init_fuzzy_mat = get_init_fuzzy_mat(pixel_count)

# 初始聚类中心

init_centroids = get_centroids(image_array, init_fuzzy_mat)

fuzzy_mat, centroids, target_function = fcm(init_fuzzy_mat, init_centroids, image_array)

label = get_label(fuzzy_mat, image_array)

new_image = label.reshape(rows, cols)

cv2.imshow("result", new_image)

cv2.imwrite("fcm_result.jpg",new_image)

cv2.waitKey(0)

cv2.destroyAllWindows()

适用于小图像分割,大图像速度非常慢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FCM(模糊C均值)是一种基于聚类的图像分割方法,它将图像中的像素划分为多个类别,并且每个类别的像素具有相似的属性。FCM算法基于模糊逻辑,可以根据像素点与各个聚类中心之间的距离来计算每个像素点属于每个聚类的概率,从而得到一个模糊的图像分割结果。FCM算法在处理噪声较少、图像对比度较强的图像时效果较好。 在Python中,可以使用skimage库来实现FCM图像分割。skimage库提供了一个名为“fuzzycmeans”的函数,可以对输入的图像进行模糊C均值聚类,得到一个分割结果。使用该函数时需要指定聚类数量和迭代次数等参数,以及指定输入图像和输出分割结果的路径等参数。 下面是一个示例代码,展示了如何使用skimage库进行FCM图像分割: ``` import numpy as np import matplotlib.pyplot as plt from skimage import io, img_as_float from skimage.filters import threshold_otsu from skimage.segmentation import fuzzycmeans # 读入图像并转换为灰度图 image = img_as_float(io.imread('input_image.png', as_gray=True)) # 使用OTSU方法计算阈值 thresh = threshold_otsu(image) # 将图像二值化 binary = image > thresh # 调用fuzzycmeans函数进行FCM聚类 centers, fcm_image = fuzzycmeans(binary, c=3, m=2, max_iter=100, error=1e-5, init=None) # 将分割结果保存为图像文件 io.imsave('output_image.png', fcm_image) # 显示原始图像和分割结果 fig, ax = plt.subplots(ncols=2, figsize=(8, 4)) ax.imshow(binary, cmap='gray') ax.set_title('Binary image') ax.imshow(fcm_image) ax.set_title('FCM segmentation') plt.show() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值