基于 Numpy - MiniSom 创建颜色量化模型

概述

颜色量化

减少原图像中所用颜色,让新图像尽可能地从视觉上和原图像相似。
搭建一个模型,可以学习一张图像中的颜色,然后用学到的知识来重构原图像。

系统环境

macOS 10.14

实验

环境搭建

安装Numpy

python -m pip install numpy scipy matplotlib

下载后可能需要退出命令行重新进入

下载 MiniSom

python
pip install minisom

安装PIL

sudo pip install Pillow 

导入

导入 MiniSom 类,以及 Numpy 和 matplotlib

from minisom import MiniSom
import numpy as np
import matplotlib.pyplot as plt

注意MiniSom大小写

加载图像

使用 matplotlib 的 imread 实用程序, 将图像加载为一个数组。

右键->拷贝图像可复制路径,注意图片格式

img = plt.imread(‘/Users/yangxiaoyan/Desktop/pig.jpg’)

使用 matplotlib 中的 imshow 函数来查看加载后的图像。

plt.imshow(img)

检查一下加载后的图像形状。

Img.shape

img.shape
可以看到它是一个 3D 矩阵。将1080乘以1440 ,把数组转换为一个 2D 数组。再用 Numpy 的 shape 属性来检查它的形状。

pixels = np.reshape(img, (img.shape[0]*img.shape[1], 3))
Pixels.shape

SOM 初始化和训练

初始化 MiniSom 对象并将其分配给变量 som

som = MiniSom(x= 3, y = 3, input_len = 3, sigma=0.1, learning_rate=0.2)

som参数

  1. 维度 - 构建一个 3*3 的 SOM,即得到的最终颜色将是 3 * 3,即 9。SOM 越大,训练所需的时间就越长。
  2. input_len - 数据集中的特征数量。使用 3,对应像素数组的形状。如果使用其它数字,会得到一个值错误异常,指示 MiniSom 无法将形状(3)中的输入数组发送到你选择的数字中。
  3. sigma - SOM 中不同相邻节点的半径,默认值为 1.0。
  4. learning_rate - 每次迭代期间权重的调整幅度。

将SOM的权重初始化为小的标准化随机值
使用random_weights_init函数并传入数据(像素)

som.random_weights_init(pixels)

保存起始权重,它们代表图像的初始颜色。稍后会将它们可视化。
使用 get_weights 函数和 Python 的副本来确保在权重更新之前得到它们。

starting_weights = som.get_weights().copy()

通过运行 train_random 函数来训练像素。它需要两个参数,第一个参数是需要训练的数据集,第二个参数是迭代次数。

som.train_random(pixels, 50)

向量量化

量化图像的每个像素,减少图像中的颜色数量。
使用 MiniSom 中的 quantization 实用程序。

qnt = som.quantization(pixels)

创建新图像

过程的开始将图像转换成 2D 数组。但现在将图像构建为 3D 图像。
用在开头加载的图像维度创建一个只有零的矩阵来完成这项工作。
借助 Numpy 的 zero 实用程序

clustered = np.zeros(img.shape)

将量化后的值放入新图像中。
使用 Numpy 的 unravel_index 功能。这个函数有三个参数:

  1. indices - array_like
    一个整数数组,其元素是维度变成数组的平铺版本的索引。

  2. dims
    整数元组整数元组

  3. Order:{‘C’,‘F’},可选
    确定是否应将索引视为以行主(C样式)或列主(Fortran样式)顺序编制索引。

    for i, q in enumerate(qnt):
        clustered [np.unravel_index(i, dims=(img.shape[0], img.shape[1]))] = q
    

注意缩进

显示结果

Matplotlib 可用 imshow 在轴上绘制图像。
使用一个 Matplotlib 图和 4 个子图来完成绘图。第一个和第二个子图将显示原始图像和新图像。第三和第四个子图将显示初始图像颜色和 SOM 学习的颜色。

创建一个 12*6 的图像。然后创建子图,它有 3 个参数:行数,列数和图索引。当这些数字小于 10 时,可以作为三位数传递,如下所示。然后使用 Matplotlib 的 imshow 来绘制图像。

plt.figure(figsize=(12, 6))
plt.subplot(221) 
plt.title('Original') 
plt.imshow(img) 
plt.subplot(222) 
plt.title('Result') 
plt.imshow(clustered)

以类似的方式创建第三和第四个子图。

plt.subplot(223)
plt.title('Initial Colors')
plt.imshow(starting_weights)
plt.subplot(224)
plt.title('Learnt Colors')
plt.imshow(som.get_weights())

使用 tight_layout 功能来确保绘图不会挤在一起。最后,使用 plt.show()绘制它们。

plt.tight_layout()
plt.show()

如果出现图像不显示问题

import pylon
put.imshow(img)
pylon.show()

成功搭建了一个 SOM 网络,能够完成颜色量化任务,重构原图像。

运行结果

第一次:图像选择失败,原有颜色过少
在这里插入图片描述

第二次
在这里插入图片描述

参考文章

SOM是怎样一种模型(对于初学者如何操作,算法等)? - 景略集智的回答 - 知乎
https://www.zhihu.com/question/28046923/answer/499882606

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值