SNN图像脉冲化——泊松编码

与ANN能够直接接收图像的像素值不同,SNN的输入是异步脉冲序列。因此将二维图像输入SNN之前,需要对图像进行脉冲化。常用的一种脉冲化方法为泊松编码

一、原理

泊松编码:将输入数据编码为发放次数分布符合泊松过程的脉冲序列

对于二维图像,每一个像素都能生成相互独立的泊松编码:

  • 预先设定总时间 T;
  • 每一个时间步,每一个像素产生脉冲的概率与该像素值成比例;
  • 执行 T个时间步,分别得到各个像素对应的脉冲序列;
  • 将每个像素产生的脉冲序列输入到对应神经元 / SNN输入层异步接收到各个像素的脉冲。

理解:

  • 根据像素值设定每个时间步产生脉冲的概率,模拟一段时间,得到脉冲序列;
  • 这段时间内可能产生的脉冲数量符合泊松分布 / 该脉冲产生过程是泊松过程;
  • 这段时间平均脉冲发放数对应泊松分布公式中的  ;
  • 通过将多个时间步的脉冲矩阵叠加,可以还原出原图像。
像素的编码与重建
像素的编码与重建

二、实例

测试代码实现了PNG图像的泊松编码(这里仅对RGB三通道进行了脉冲化)。

import numpy as np
from PIL import Image

image = Image.open('PIC/WOODSTOCK.png')

data_ori = np.array(image)                  # original
print('SHAPE:', data_ori.shape)
x = data_ori.shape[0]
y = data_ori.shape[1]

data_pro = data_ori.astype('float')[:]      # probability
data_new = data_ori[:]                      # reconducted
frames_new = []                             # to gif

data_poisson = data_ori.tolist()            # code
for i in range(x):
    for j in range(y):
        for k in range(3):
            data_poisson[i][j][k] = ''

t_simu = 255

# probability matrix
for row in data_pro:
    for pixel in row:
        pixel[:3] /= 255

# generate poisson code
for t in range(t_simu):
    print('Proccessing  %d/%d' % (t+1, t_simu))
    for i in range(x):
        for j in range(y):
            for k in range(3):
                if np.random.random() < data_pro[i][j][k]:
                    data_poisson[i][j][k] += '1'
                else:
                    data_poisson[i][j][k] += '0'

    # add temporary png to gif
    if not (t % 15):
        for i in range(x):
            for j in range(y):
                for k in range(3):
                    data_new[i][j][k] = data_poisson[i][j][k].count('1')

        Image.fromarray(data_new).save('temp/temp_%d.png' % t)
        frames_new.append(Image.open('temp/temp_%d.png' % t))

# output poisson code
with open('Poison.out', 'w') as file:
    for i in range(x):
        for j in range(y):
            for k in range(3):
                file.write(data_poisson[i][j][k] + '\n')
                data_new[i][j][k] = data_poisson[i][j][k].count('1')
            file.write('\n')

img = Image.fromarray(data_new)
img.save('reconduct.png')
frames_new[0].save('reconduct.gif', save_all=True, append_images=frames_new, duration=500, loop=1)

该实例中,首先将像素值归一化作为脉冲发放概率,模拟255个时间步,每个像素各个通道产生的泊松编码保存在文件Poisson.out中。

某像素三通道泊松编码片段

重建图像reconduct.png能够较准确地还原图像,说明得到的编码较好地保留了原图像信息;reconduct.gif复现了编码过程中不同时间步下的重建图像。

reconduct.gif

猜你喜欢

转载自blog.csdn.net/weixin_54633033/article/details/131824663
今日推荐