好奇的小老鼠——使用FCM对图片像素进行聚类

简介: 好奇的小老鼠——使用FCM对图片像素进行聚类

FCM

FCM,英文全程Fuzzy C-Means(FCM),关于FCM,网络上有不少文章,笔者之前也写过一篇介绍FCM的文章,👉《机器学习之聚类——模糊聚类FCM》,感兴趣的读者可以看一下哈!!

图片像素聚类

众所周知,图片是由二维平面上的像素点组成的,灰度图的每个像素点都对应一个像素值 (0 − 255 0-2550255),而彩色图片的像素点会对应三原色以及透明度四个值。

本文会将图片转换为灰度图,然后对像素点进行聚类,在对灰度图像素点进行聚类时,有一点非常重要,因为灰度图的每个像素点都只对应一个像素值,所以对灰度图像素的聚类可以视为对一维数据的聚类问题。

看,我们的操作对象就是这个好奇的小老鼠,读者也可以换成其他的图片哟!

代码

FCM部分代码(fcm.py):

import numpy as np
class FCM:
    def __init__(self, K, m=2, eps=0.05):
        # 聚类个数
        self.K = K
        # 加权参数
        self.m = m
        # 终止容限
        self.eps = eps
        # 最优相似度矩阵
        self.U = None
        # 最终的聚类中心
        self.centers = None
        # 目标函数值
        self.obj_val = None
    def init_by_centers(self, data, centers):
        # 初始化隶属度矩阵
        self.U = np.random.random((len(data), self.K))
        # 样本到聚类中心的距离
        dist = np.zeros((len(data), self.K))
        for i, x in enumerate(data):
            for j, c in enumerate(centers):
                dist[i][j] = np.linalg.norm(x - c, 2)
        # 计算新的隶属度矩阵
        for i, x in enumerate(data):
            for j, c in enumerate(centers):
                self.U[i][j] = 1./np.sum((dist[i][j]/dist[i]) ** (2/(self.m-1)))
        # 最初的目标函数值
        self.obj_val = np.sum((self.U ** self.m) * (dist ** 2))
    def train(self, data):
        if len(data.shape) == 1:
            data = data[:, np.newaxis]
        if self.U is None:
            # 初始化隶属度矩阵
            self.U = np.random.random((len(data), self.K))
            # 保证每个样本属于所有类的概率是1
            self.U = np.divide(self.U, np.sum(self.U, axis=1)[:, np.newaxis])
        while True:
            temp_U = self.U ** self.m
            # 计算聚类中心
            self.centers = np.divide(np.dot(temp_U.T, data), np.sum(temp_U.T, axis=1)[:, np.newaxis])
            # 样本到聚类中心的距离
            dist = np.zeros((len(data), self.K))
            for i, x in enumerate(data):
                for j, c in enumerate(self.centers):
                    dist[i][j] = np.linalg.norm(x - c, 2)
            # 计算新的隶属度矩阵
            for i, x in enumerate(data):
                for j, c in enumerate(self.centers):
                    temp_U[i][j] = 1./np.sum((dist[i][j]/dist[i]) ** (2/(self.m-1)))
            # 判断是否收敛
            if np.sum(abs(temp_U-self.U)) < self.eps:
                break
            # 更新隶属度矩阵
            self.U = temp_U
            # 更新目标函数值
            self.obj_val = np.sum((self.U ** self.m) * (dist ** 2))
        # 返回样本最大隶属度对应的类别
        return np.argmax(self.U, axis=1)
    def __str__(self) -> str:
        return f"K:{self.K}, m:{self.m}, eps:{self.eps}, U:{self.U}, centers:{self.centers}, dist: {self.dist}"

图片像素聚类主程序代码:

from matplotlib import pyplot as plt
import time
import cv2
from fcm import *
# 导入图片
def import_image(img_path):
    # 导入图片并转换成灰度图像,其中的像素值是0-255,uint8类型
    img = cv2.imread(img_path, 0)
    # 图片尺寸
    h, w = img.shape
    img = img.astype('float')
    return img, h, w
def run():
    # 开始计时
    begin = time.time()
    img_path = "./mouse.jpeg"
    # 聚类的数量
    c = 2
    # 导入图像
    img, h, w = import_image(img_path)
    # 去重后的图片像素值
    pixel_data = np.unique(img.flatten())
    # FCM模型
    my_fcm = FCM(K=c, m=2, eps=0.01)
    # 优化
    y = my_fcm.train(pixel_data)
    end = time.time()
    print("总共花费了时间{}".format(end - begin))
    print("像素值聚类中心:{}".format(my_fcm.centers.flatten()))
    print("目标函数值:{}".format(my_fcm.obj_val))
    # 像素值及其对应的类别标签
    pixel_label = dict()
    for d, l in zip(pixel_data, y):
        pixel_label[d] = l
    # 按像素类别生成新的图片
    img_new = np.zeros((h, w))
    # 遍历每一个像素
    for i in range(h):
        for j in range(w):
            img_new[i][j] = int(pixel_label[img[i][j]])
    # 绘制图片
    plt.imshow(img_new, cmap='gray')
    plt.gca().xaxis.set_major_locator(plt.NullLocator())
    plt.gca().yaxis.set_major_locator(plt.NullLocator())
    plt.show()
    # plt.savefig('fcm_mouse.png', dpi=800)
if __name__ == "__main__":
    run()

输出图片如下,还是挺好玩的吧

作者这水平有限,有不足之处欢迎留言指正

相关文章
|
10月前
|
数据可视化
R语言绘图教程丨Nature论文都在用的多组比较箱线图,自动计算显著性并标注,附带误差线
R语言绘图教程丨Nature论文都在用的多组比较箱线图,自动计算显著性并标注,附带误差线
|
16天前
|
机器学习/深度学习 算法 数据可视化
【从零开始学习深度学习】46. 目标检测中锚框的概念、计算方法、样本锚框标注方式及如何选取预测边界框
【从零开始学习深度学习】46. 目标检测中锚框的概念、计算方法、样本锚框标注方式及如何选取预测边界框
|
1月前
|
传感器 人工智能 搜索推荐
用 ChatGPT 4.0 实现获取并保存 RealSense 相机的深度图像,处理colorizer,histogram equalization配置,解决深度图像颜色分布异常问题
用 ChatGPT 4.0 实现获取并保存 RealSense 相机的深度图像,处理colorizer,histogram equalization配置,解决深度图像颜色分布异常问题
56 0
用 ChatGPT 4.0 实现获取并保存 RealSense 相机的深度图像,处理colorizer,histogram equalization配置,解决深度图像颜色分布异常问题
|
1月前
|
算法
暗通道先验算法
暗通道先验算法
49 0
|
10月前
|
机器学习/深度学习 编解码 算法
【阿里云OpenVI-视觉生产系列之图片上色】照片真实感上色算法DDColor ICCV2023论文深入解读
图像上色是老照片修复的一个关键步骤,本文介绍发表在 ICCV 2023 上的最新上色论文 DDColor
2294 10
【阿里云OpenVI-视觉生产系列之图片上色】照片真实感上色算法DDColor ICCV2023论文深入解读
|
9月前
|
编解码 人工智能 移动开发
AIGC图像分辨率太低?快来试试像素感知扩散超分模型,你想要的细节都在这里
阿里巴巴最新自研的像素感知扩散超分模型已经开源,它把扩散模型强大的生成能力和像素级控制能力相结合,能够适应从老照片修复到AIGC图像超分的各种图像增强任务和各种图像风格,并且能够控制生成强度和增强风格。这项技术的直接应用之一是AIGC图像的后处理增强和二次生成,能够带来可观的效果提升。
|
9月前
|
机器学习/深度学习 传感器 算法
垂直腔表面发射激光器极化噪声的建模与分析论文复现
垂直腔表面发射激光器极化噪声的建模与分析论文复现
|
机器学习/深度学习 编解码 算法
CV之NoGAN:利用图像增强技术(图片上色)实现对旧图像和电影片段进行着色和修复(爱因斯坦、鲁迅旧照/清末官员生活场景等案例)
CV之NoGAN:利用图像增强技术(图片上色)实现对旧图像和电影片段进行着色和修复(爱因斯坦、鲁迅旧照/清末官员生活场景等案例)
CV之NoGAN:利用图像增强技术(图片上色)实现对旧图像和电影片段进行着色和修复(爱因斯坦、鲁迅旧照/清末官员生活场景等案例)
|
11月前
|
存储 监控 计算机视觉
基于颜色特征的图像检索系统
基于颜色特征的图像检索系统。
96 0
|
机器学习/深度学习 传感器 算法
【方位估计】基于music算法实现均匀圆阵方位估计附matlab代码
【方位估计】基于music算法实现均匀圆阵方位估计附matlab代码