图像局部对比度归一化(LCN)

1. 灰度图像局部对比度归一化

代码1:
def LocalNormalization(patch, P=3, Q=3, C=1):
    kernel = np.ones((P, Q)) / (P * Q)
    patch_mean = convolve2d(patch, kernel, boundary='symm', mode='same')
    patch_sm = convolve2d(np.square(patch), kernel, boundary='symm', mode='same')
    patch_std = np.sqrt(np.maximum(patch_sm - np.square(patch_mean), 0)) + C
    patch_ln = torch.from_numpy((patch - patch_mean) / patch_std).float().unsqueeze(0)

 

代码2:

import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
import pdb

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

def local_contrast_norm(image,radius=9):
    """
    image: torch.Tensor , .shape => (1,channels,height,width) 
    
    radius: Gaussian filter size (int), odd
    """
    if radius%2 == 0:# LCN核的大小为奇数
        radius += 1
    def get_gaussian_filter(kernel_shape):
        x = np.zeros(kernel_shape, dtype='float64')
         
         #二维高斯函数
        def gauss(x, y, sigma=2.0):
            Z = 2 * np.pi * sigma ** 2
            return  1. / Z * np.exp(-(x ** 2 + y ** 2) / (2. * sigma ** 2))
 
        mid = np.floor(kernel_shape[-1] / 2.)#求出卷积核的中心位置(mid,mid)
        for kernel_idx in range(0, kernel_shape[1]):#遍历每一层
            for i in range(0, kernel_shape[2]):#遍历x轴
                for j in range(0, kernel_shape[3]):#遍历y轴
                    x[0, kernel_idx, i, j] = gauss(i - mid, j - mid)#计算出高斯权重
 
        return x / np.sum(x)
    
    n,c,h,w = image.shape[0],image.shape[1],image.shape[2],image.shape[3]#(图片数、层数、x轴、y轴大小)

    gaussian_filter = torch.Tensor(get_gaussian_filter((1,c,radius,radius))).to(device)#创建卷积核
    filtered_out = F.conv2d(image,gaussian_filter,padding=radius-1)#卷积 (∑ipq Wpq.X i,j+p,k+q)
    mid = int(np.floor(gaussian_filter.shape[2] / 2.))#获得卷积核的中心位置

    ### Subtractive Normalization
    centered_image = image - filtered_out[:,:,mid:-mid,mid:-mid] # Vijk 
    #↑由于padding为radius-1,filered_out比实际图片要大,截取mid:-mid后才是有效区域)

    ## Variance Calc
    sum_sqr_image = F.conv2d(centered_image.pow(2),gaussian_filter,padding=radius-1)# ∑ipqWpq.v2 i,j+p,k+q
    s_deviation = sum_sqr_image[:,:,mid:-mid,mid:-mid].sqrt()# σ jk
    per_img_mean = s_deviation.mean() # c
    
    ## Divisive Normalization
    divisor = np.maximum(per_img_mean.cpu().detach().numpy(),s_deviation.cpu().detach().numpy())#max(c, σjk)
    divisor = np.maximum(divisor, 1e-4)
    new_image = centered_image / torch.Tensor(divisor).to(device) #Yijk

    return new_image.to(device)

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值