参考资料与文献:
参考博客1
本博客部分参考上文链接,只是记录学习所用,若侵权,联系删除
[1]C.P. Chen, H. Li, Y. Wei, T. Xia, Y.Y. Tang, A local contrast method for small infrared target detection, IEEE Trans. Geosci. Remote Sens. 52 (1) (2014) 574–581.
[2]Y. Wei, X. You, and H. Li, “Multiscale patch-based contrast measure for small infrared target detection,” Pattern Recognition, vol. 58, pp. 216–226, 2016.
[3]Y Dai, Y Wu, F Zhou, et al. Attentional local contrast networks for infrared small target detection[J]. IEEE Transactions on Geoscience and Remote Sensing, 2021.
目标局部对比度的计算方法:
式中, N u N_u Nu表示子窗口中包含的像素数量, I j i I_j^i Iji表示第 i i i个子窗口内的第 j j j个像素的像素值
中心子窗口与其邻域窗口的对比度可表示为:
式中, L 0 L_0 L0表示中心子窗口的像素最大值
C的值越大,中心区域是目标的可能性越大,分析如下:
如果中心区域是目标,则 L 0 / m i > 1 L_0/m_i >1 L0/mi>1,进而 C = L 0 ∗ L 0 / m i > L 0 C = L_0*L_0/m_i >L_0 C=L0∗L0/mi>L0;
如果中心区域不是目标,则 L 0 / m i < 1 L_0/m_i <1 L0/mi<1,进而 C = L 0 ∗ L 0 / m i < = L 0 C = L_0*L_0/m_i <=L_0 C=L0∗L0/mi<=L0。
由此,目标区域像素值得到增强,背景得到抑制;
该算法的缺点是:
滑动窗口被分为两部分(与LCM算法一致),将背景分为8部分,该步骤的操作目的是为了增强目标并一致背景。
目标子窗口与背景之间的区别定义为:
其中 d d d表示目标与背景的差异程度。 d d d的计算方式有多种,本文选择的是均值作差,即 d ( T , B i ) = m T − m B i , ( i = 1 , 2 , . . . , 8 ) d(T,B_i)=m_T-m_{B_i}, (i=1,2,...,8) d(T,Bi)=mT−mBi,(i=1,2,...,8),其中 m T m_T mT, m B i m_{B_i} mBi分别为目标区域与背景子区域的像素均值。
上式给出了某一尺度下局部对比度的度量方法,基于目标与背景的灰度差异,进一步提出:
——————————————(2)
d i ~ \widetilde{d_i} di 表示了中心区域与周围邻域在四个方向上的灰度差异,如果 d i ~ > 0 \widetilde{d_i}>0 di >0,则表示中心区域与邻域的差异是一致的,要么比中心区域亮,要么比中心区域暗,因此可以衡量目标区域的特征。如果 d i ~ < 0 \widetilde{d_i}<0 di <0,则中心区域与邻域的差异不一致,即对比度较大。
目标与背景之间的对比度越大越好,因此本文定义某一尺度下目标的对比度测量方式pathc-based contrast measure(PCM)为:
式中, ( x i i , y j j ) (x_{ii},y_{jj}) (xii,yjj)表示目标区域的中心位置的坐标。
引入膨胀卷积的概念(注意实际操作没用膨胀卷积,只是借用了这个概念),这样就将patch尺度的问题就转化为膨胀率这个超参的问题。
假设一个特征图 F F F,尺度为 C , H , W C,H,W C,H,W,某像素点 ( c , i , j ) (c,i,j) (c,i,j)和膨胀率 d d d,则上述公式(2)表示为:
——————————————(1)
其中(x,y)表示四个方向
则最终某点 ( c , i , j ) (c,i,j) (c,i,j)在膨胀率为 d d d的局部特征为:
——————————————(2)
为了加快训练速度,利用下述公式组合拼接特征图:
——————————————(3)
S代表的是F进行Cyclic Shift后的特征图。
最后的局部对比度特征为四个方向D的最大值。
——————————————(4)
如下图所示
def circ_shift(cen, shift):
_, _, hei, wid = cen.shape
######## B1 #########
# old: AD => new: CB
# BC => DA
B1_NW = cen[:, :, shift:, shift:] # B1_NW is cen's SE
B1_NE = cen[:, :, shift:, :shift] # B1_NE is cen's SW
B1_SW = cen[:, :, :shift, shift:] # B1_SW is cen's NE
B1_SE = cen[:, :, :shift, :shift] # B1_SE is cen's NW
B1_N = nd.concat(B1_NW, B1_NE, dim=3)
B1_S = nd.concat(B1_SW, B1_SE, dim=3)
B1 = nd.concat(B1_N, B1_S, dim=2)
######## B2 #########
# old: A => new: B
# B => A
B2_N = cen[:, :, shift:, :] # B2_N is cen's S
B2_S = cen[:, :, :shift, :] # B2_S is cen's N
B2 = nd.concat(B2_N, B2_S, dim=2)
######## B3 #########
# old: AD => new: CB
# BC => DA
B3_NW = cen[:, :, shift:, wid-shift:] # B3_NW is cen's SE
B3_NE = cen[:, :, shift:, :wid-shift] # B3_NE is cen's SW
B3_SW = cen[:, :, :shift, wid-shift:] # B3_SW is cen's NE
B3_SE = cen[:, :, :shift, :wid-shift] # B1_SE is cen's NW
B3_N = nd.concat(B3_NW, B3_NE, dim=3)
B3_S = nd.concat(B3_SW, B3_SE, dim=3)
B3 = nd.concat(B3_N, B3_S, dim=2)
######## B4 #########
# old: AB => new: BA
B4_W = cen[:, :, :, wid-shift:] # B2_W is cen's E
B4_E = cen[:, :, :, :wid-shift] # B2_E is cen's S
B4 = nd.concat(B4_W, B4_E, dim=3)
######## B5 #########
# old: AD => new: CB
# BC => DA
B5_NW = cen[:, :, hei-shift:, wid-shift:] # B5_NW is cen's SE
B5_NE = cen[:, :, hei-shift:, :wid-shift] # B5_NE is cen's SW
B5_SW = cen[:, :, :hei-shift, wid-shift:] # B5_SW is cen's NE
B5_SE = cen[:, :, :hei-shift, :wid-shift] # B5_SE is cen's NW
B5_N = nd.concat(B5_NW, B5_NE, dim=3)
B5_S = nd.concat(B5_SW, B5_SE, dim=3)
B5 = nd.concat(B5_N, B5_S, dim=2)
######## B6 #########
# old: A => new: B
# B => A
B6_N = cen[:, :, hei-shift:, :] # B6_N is cen's S
B6_S = cen[:, :, :hei-shift, :] # B6_S is cen's N
B6 = nd.concat(B6_N, B6_S, dim=2)
######## B7 #########
# old: AD => new: CB
# BC => DA
B7_NW = cen[:, :, hei-shift:, shift:] # B7_NW is cen's SE
B7_NE = cen[:, :, hei-shift:, :shift] # B7_NE is cen's SW
B7_SW = cen[:, :, :hei-shift, shift:] # B7_SW is cen's NE
B7_SE = cen[:, :, :hei-shift, :shift] # B7_SE is cen's NW
B7_N = nd.concat(B7_NW, B7_NE, dim=3)
B7_S = nd.concat(B7_SW, B7_SE, dim=3)
B7 = nd.concat(B7_N, B7_S, dim=2)
######## B8 #########
# old: AB => new: BA
B8_W = cen[:, :, :, shift:] # B8_W is cen's E
B8_E = cen[:, :, :, :shift] # B8_E is cen's S
B8 = nd.concat(B8_W, B8_E, dim=3)
return B1, B2, B3, B4, B5, B6, B7, B8
def cal_pcm(cen, shift):
B1, B2, B3, B4, B5, B6, B7, B8 = circ_shift(cen, shift=shift)
s1 = (B1 - cen) * (B5 - cen)
s2 = (B2 - cen) * (B6 - cen)
s3 = (B3 - cen) * (B7 - cen)
s4 = (B4 - cen) * (B8 - cen)
c12 = nd.minimum(s1, s2)
c123 = nd.minimum(c12, s3)
c1234 = nd.minimum(c123, s4)
return c1234
class CalMPCM(HybridBlock):
def __init__(self, **kwargs):
super(CalMPCM, self).__init__(**kwargs)
def hybrid_forward(self, F, x):
pcm9 = cal_pcm(x, shift=9)
pcm13 = cal_pcm(x, shift=13)
pcm17 = cal_pcm(x, shift=17)
mpcm = nd.maximum(nd.maximum(pcm9, pcm13), pcm17)
return mpcm
def evaluate(self, x):
"""evaluating network with inputs and targets"""
return self.forward(x)