通过一个空间传播网络来学习affinity matrix来用于vision tasks。实验证明,构造一个线性传播模型,空间上变换的affinity matrix可以用来建模图像密集和全局相似性。本文创建了一个three-way 连接的线性传播模型。该模型构造了一个所有元素均来自于DCNN的稀疏传播矩阵,同时创造了一个能用来建模任意特定任务的密集近邻矩阵。本文用data-driven manner来获取similarities,结果可以用在所有相似的图像任务上,包括但不限于图像分割。
邻接矩阵是用来描述两个点有多近,多相似的。在高维空间任务也有作用,但是一直没有视作为一个可学习的问题。在这个paper里我们证明学习affinity matrix等价于学习一系列row/column wise空间上线性变换的矩阵。在这里,我们发现用three-way connection比用fully connection更有效地学习dense affinity matrix。
用data-driven manner学习affinity matrix的优势是多方面的(multifold)。1. 在低维空间的相似矩阵的assumption并不适用于mid-to-high-level。2. 可以学习高维的特征的affinity。
略
SPN 能够转换一个2D map成一个新的拥有希望性质的map。这个过程等价于standard anisotropic diffusion process。图像转换相当于是经过laplacian matrix转化的。(从未见过如此数学化的dcnn论文)
假设 X , H 是2D图像,大小是 n×n , xt,ht 是第 t 纵列。对于left-to-right的传播,有如下跟新规则。
G 的每一行元素合起来等于1
对于演化矩阵 {U}T ,有 ∂TU=−LU ,L是拉普拉斯矩阵,D是degree矩阵,A是affinity matrix。
定理2证明了 (1)是一个标准的扩散过程, L 定义了空间传播, A 邻接矩阵描述了两个点之间的相似程度。所以学习 A 和学习 ω 是一样的。关键在于怎么让深度学习网络学习邻接矩阵。
因为邻接矩阵用来描述特定输入的图像的相似,所以肯定需要data有关。输入是 c 通道,输出是 n×c×4 通道。这个计算量太大,所以就证明了certain local connections可以实现。
然后证明了一波three-way connection更好。简而言之就是每一个pixel与前一个row/column的三个pixel连接比只连接一个pixel更好。
证明了该变换是stability的。
两个部分:
(a). 一个deep CNN输出transformation matrix。
(b). 一个线性传播module,输出propagation结果。
在deep CNN输入一张图像,大小为 n×n×n×c ,输出的就是 n×n×n×c×(3×4) 。
3个不同的点和4个传播方向
SPN可以用来联合训练任意的segmentation model,作为一个refinement的工具。接下来就是测试的数据和流程。结果就是显著提高效果。
引用来源于万能的知乎
https://www.zhihu.com/question/24591127
以及csdn博客
http://blog.csdn.net/Marco_L_T/article/details/72888138
http://blog.csdn.net/bluecol/article/details/46690985
http://blog.csdn.net/EbowTang/article/details/43016451
一个图的邻接矩阵 G :对于无向图的边 (u,v) , G[u][v]++,G[v][u]++
一个图的度数矩阵 D :对于无向图的边 (u,v) , D[u][u]++,D[v][v]++
拉普拉斯矩阵为:
以电磁理论的电荷守恒为例子,很容易有
同样地在图像中用梯度算子配合以连续性方程可以平滑图像。这就是用 I(x,y) 代替 ρ 。但是连续性方程式四向均匀的,所以就有个PM方程:
图像边缘在梯度值较大的点处,如果扩散房产在梯度值较大的区域减速扩散,在梯度值小的加速扩散,就可以去噪的同时又保护细节
import numpy as np
import math
import scipy.ndimage
from scipy import misc as misc
np.set_printoptions(threshold=np.inf)
def anisodiff2d(image, num_iter, delta_t, kappa, activation):
"""
:param image: 输入图像
:param num_iter: 滤波次数
:param delta_t: 积分常数 0 - 1 /7
:param kappa: 梯度阈值
:param activation: 扩散函数
:return: 扩散图像
"""
init_im = image
# 初始矩阵
dx = 1
dy = 1
dd = math.sqrt(2)
# 距离
lu = np.array([[1, 0, 0], [0, -1, 0], [0, 0, 0]])
uu = np.array([[0, 1, 0], [0, -1, 0], [0, 0, 0]])
ru = np.array([[0, 0, 1], [0, -1, 0], [0, 0, 0]])
lm = np.array([[0, 0, 0], [1, -1, 0], [0, 0, 0]])
rm = np.array([[0, 0, 0], [0, -1, 1], [0, 0, 0]])
lb = np.array([[0, 0, 0], [0, -1, 0], [1, 0, 0]])
mb = np.array([[0, 0, 0], [0, -1, 0], [0, 1, 0]])
rb = np.array([[0, 0, 0], [0, -1, 0], [0, 0, 1]])
# 八个方向的掩码
for i in range(num_iter):
nable_lu = scipy.ndimage.correlate(init_im, lu, mode= 'nearest')
nable_uu = scipy.ndimage.correlate(init_im, uu, mode= 'nearest')
nable_ru = scipy.ndimage.correlate(init_im, ru, mode= 'nearest')
nable_rm = scipy.ndimage.correlate(init_im, rm, mode= 'nearest')
nable_lm = scipy.ndimage.correlate(init_im, lm, mode= 'nearest')
nable_lb = scipy.ndimage.correlate(init_im, lb, mode= 'nearest')
nable_mb = scipy.ndimage.correlate(init_im, mb, mode= 'nearest')
nable_rb = scipy.ndimage.correlate(init_im, rb, mode= 'nearest')
c_lu = activation(nable_lu, kappa)
c_uu = activation(nable_uu, kappa)
c_ru = activation(nable_ru, kappa)
c_rm = activation(nable_rm, kappa)
c_lm = activation(nable_lm, kappa)
c_lb = activation(nable_lb, kappa)
c_mb = activation(nable_mb, kappa)
c_rb = activation(nable_rb, kappa)
init_im = init_im + delta_t * (
(1 / (dd * dd)) * c_lu * nable_lu + (1 / (dy * dy)) * c_uu * nable_uu +
(1 / (dd * dd)) * c_ru * nable_ru + (1 / (dx * dx)) * c_rm * nable_rm +
(1 / (dx * dx)) * c_lm * nable_lm + (1 / (dd * dd)) * c_lb * nable_lb +
(1 / (dy * dy)) * c_mb * nable_mb + (1 / (dd * dd)) * c_rb * nable_rb
)
print("*****complete {} iteration*******".format(i + 1))
return init_im
def activation(nable, kappa):
# return np.exp(-(nable / kappa)*(nable / kappa))
return 1 / (1 + (nable / kappa) * (nable / kappa))
if __name__ == "__main__":
image = misc.imread(r"ori.jpg", mode = "RGB")
num_iter = 20
delta_t = 1/7
kappa = 20
# a = image[0]
print(np.shape(image[:,:,0]))
image[:, :, 0] = anisodiff2d(image[:,:,0], num_iter, delta_t, kappa, activation)
image[:, :, 1] = anisodiff2d(image[:,:,1], num_iter, delta_t, kappa, activation)
image[:, :, 2] = anisodiff2d(image[:,:,2], num_iter, delta_t, kappa, activation)
#ima = np.array([a.tolist(),b.tolist(),c.tolist()])
# print(a - image[0])
misc.imsave(r"new.jpg", image)
待继续填坑
跪求代码