当前位置:网站首页>[Thesis code] SML part code reading
[Thesis code] SML part code reading
2022-07-06 05:55:00 【starbuling~】
SML Boundary suppression and Gaussian smoothing in
Boundary smoothing suppression class
class BoundarySuppressionWithSmoothing(nn.Module):
""" Apply boundary suppression and dilated smoothing Boundary suppression , Expand and smooth """
initialization
def __init__(self, boundary_suppression=True, boundary_width=4, boundary_iteration=4,
dilated_smoothing=True, kernel_size=7, dilation=6):
Define some parameters
super(BoundarySuppressionWithSmoothing, self).__init__()
self.kernel_size = kernel_size # Convolution kernel size
self.dilation = dilation # expansion
self.boundary_suppression = boundary_suppression # Boundary suppression
self.boundary_width = boundary_width # Boundary width
self.boundary_iteration = boundary_iteration # Boundary iteration
Create Gaussian kernel
sigma = 1.0
size = 7
# function Is the probability density function of two-dimensional Gaussian distribution
gaussian_kernel = np.fromfunction(lambda x, y:
(1/(2*math.pi*sigma**2)) * math.e ** ((-1*((x-(size-1)/2)**2+(y-(size-1)/2)**2))/(2*sigma**2)),
(size, size)) # Construct Gaussian kernel (7,7) 3 * sigma + 1
gaussian_kernel /= np.sum(gaussian_kernel) # Divide by the sum of all elements in the Gaussian kernel ( weighted mean , Avoid image pixel overflow )
gaussian_kernel = torch.Tensor(gaussian_kernel).unsqueeze(0).unsqueeze(0)
self.dilated_smoothing = dilated_smoothing # Expand and smooth
l a m b d a ( x , y ) = 1 2 ∗ π ∗ σ 2 e x p ( − ( x − s i z e − 1 2 ) 2 + ( y − s i z e − 1 2 ) 2 2 ∗ σ 2 ) lambda(x,y) = \frac{1}{2 * \pi * \sigma^2} exp(-\frac{(x - \frac{size-1}{2})^2 + (y - \frac{size-1}{2})^2}{2 * \sigma^2}) lambda(x,y)=2∗π∗σ21exp(−2∗σ2(x−2size−1)2+(y−2size−1)2)
numpy In the library
fromfunction: Through custom functions fun, shape shape, data format dtype -> According to the array subscript (x,y) Generate values for each location , Make an array
Function parameter
np.fromfunction(function, shape, dtype)
function: A function transformed into a specific value according to coordinates
def function(x,y): Internal function (x,y) Are the coordinates with the upper left corner as the origin ,x For row coordinates ,y Column coordinates , It means the first one x That's ok y Column .shape(a,b): Represents an array array Size ,a That's ok b Column .
dtype: Represents the number type of the array
Define two-layer convolution (in_channel, out_channel, k, s)
- (1, 1, 3, 1) The weight matrix is full 1 matrix
- (1, 1, 7, 1) The weight matrix is Gaussian kernel
self.first_conv = nn.Conv2d(1, 1, kernel_size=3, stride=1, bias=False)
self.first_conv.weight = torch.nn.Parameter(torch.ones_like((self.first_conv.weight)))
self.second_conv = nn.Conv2d(
1, 1, kernel_size=self.kernel_size, stride=1, dilation=self.dilation, bias=False)
self.second_conv.weight = torch.nn.Parameter(gaussian_kernel)
Forward propagation
def forward(self, x, prediction=None):
if len(x.shape) == 3:
x = x.unsqueeze(1) # If it is 3 dimension , expand 1 dimension
x_size = x.size()
# B x 1 x H x W
assert len(x.shape) == 4
out = x
Branch 1: Need boundary suppression
if self.boundary_suppression:
# obtain the boundary map of width 2 by default The default acquisition width is 2 Boundary graph of
# this can be calculated by the difference of dilation and erosion This can be calculated by the difference between expansion and corrosion
boundaries = find_boundaries(prediction.unsqueeze(1)) # Look for boundaries
expanded_boundaries = None
if self.boundary_iteration != 0:
assert self.boundary_width % self.boundary_iteration == 0 # The boundary width is divided by the number of iterations
diff = self.boundary_width // self.boundary_iteration # Width increased each time
The main process of boundary suppression
for iteration in range(self.boundary_iteration):
if len(out.shape) != 4:
out = out.unsqueeze(1)
prev_out = out
Get the boundary
# if it is the last iteration or boundary width is zero The last iteration or boundary width is 0 after , Stop expanding width if self.boundary_width == 0 or iteration == self.boundary_iteration - 1: expansion_width = 0 # reduce the expansion width for each iteration Otherwise, the width of the freight station will be continuously increased in each iteration else: expansion_width = self.boundary_width - diff * iteration - 1 # expand the boundary obtained from the prediction (width of 2) by expansion rate expanded_boundaries = expand_boundaries(boundaries, r=expansion_width) # Expand the boundary according to the expansion width , The specific method is explained in detail in the function laterReverse the boundary -> Get a non boundary mask
# invert it so that we can obtain non-boundary mask non_boundary_mask = 1. * (expanded_boundaries == 0) # Reverse the boundary , Get the non boundary mask . The non boundary is 1, The boundary is 0Make the boundary area to 0
f_size = 1 num_pad = f_size # making boundary regions to 0 x_masked = out * non_boundary_mask # The input image * Non boundary mask -> Get the non boundary region (1) x_padded = nn.ReplicationPad2d(num_pad)(x_masked) non_boundary_mask_padded = nn.ReplicationPad2d(num_pad)(non_boundary_mask)class torch.nn.ReplicationPad2d(padding)
padding(int ,tuple) The size of the fill . If int , Then use the same fill in all boundaries .
If it is 4 tuple , Then use (padding_left, padding_right, padding_top, padding_bottom)Sum the values in the receptive field
# sum up the values in the receptive field y = self.first_conv(x_padded) # count non-boundary elements in the receptive field num_calced_elements = self.first_conv(non_boundary_mask_padded) num_calced_elements = num_calced_elements.long()Averaging
# take an average by dividing y by count # if there is no non-boundary element in the receptive field, # keep the original value avg_y = torch.where((num_calced_elements == 0), prev_out, y / num_calced_elements) out = avg_yUpdate boundaries
# update boundaries only out = torch.where((non_boundary_mask == 0), out, prev_out) del expanded_boundaries, non_boundary_mask
The second step : Expand and smooth
# second stage; apply dilated smoothing
if self.dilated_smoothing == True:
out = nn.ReplicationPad2d(self.dilation * 3)(out)
out = self.second_conv(out)
return out.squeeze(1)
Branch 1: No boundary suppression is required
else:
if self.dilated_smoothing == True: # Expand and smooth
out = nn.ReplicationPad2d(self.dilation * 3)(out)
out = self.second_conv(out)
else:
out = x
return out.squeeze(1)
find_boundaries
def find_boundaries(label):
""" Calculate boundary mask by getting diff of dilated and eroded prediction maps """
assert len(label.shape) == 4
boundaries = (dilation(label.float(), selem_dilation) != erosion(label.float(), selem)).float()
### save_image(boundaries, f'boundaries_{boundaries.float().mean():.2f}.png', normalize=True)
return boundaries
selem = torch.ones((3, 3)).cuda() # It's a (3,3) Full size 1 Tensor , Corrosion coil nucleation
selem_dilation = torch.FloatTensor(ndi.generate_binary_structure(2, 1)).cuda() # Expanded convolution kernel
corrosion :
inflation :
inflation (dilation) & corrosion (erosion)
These are two basic morphological operations , It is mainly used to find the maximum and minimum regions in the image .
- Expansion is similar to ‘ Domain expansion ’ , Expand the highlighted area or white part of the image , The operation result graph is larger than the highlighted area of the original graph .
- Corrosion similar ‘ The field is being eroded ’ , Reduce and refine the highlighted area or white part of the image , The operation result is smaller than the highlighted area of the original image .
The specific process : Define a convolution kernel , Convolute the picture . Expansion do “ or ” operation , expand 1 The scope of the ; Corrosion makes “ And ” operation , Reduce 1 The number of
dilation(image, kernel) # Images , Convolution kernel
erosion(image, kernel)
After expansion and corrosion of the label drawings , Different positions , It's the boundary . use 1 Express
expand_boundaries
def expand_boundaries(boundaries, r=0):
""" Expand boundary maps with the rate of r """
if r == 0:
return boundaries
expanded_boundaries = dilation(boundaries, d_ks[r]) # Do the expansion operation
### save_image(expanded_boundaries, f'expanded_boundaries_{r}_{boundaries.float().mean():.2f}.png', normalize=True)
return expanded_boundaries
About d_ks[]:
d_k1 = torch.zeros((1, 1, 2 * 1 + 1, 2 * 1 + 1)).cuda()
d_k2 = torch.zeros((1, 1, 2 * 2 + 1, 2 * 2 + 1)).cuda()
d_k3 = torch.zeros((1, 1, 2 * 3 + 1, 2 * 3 + 1)).cuda()
d_k4 = torch.zeros((1, 1, 2 * 4 + 1, 2 * 4 + 1)).cuda()
d_k5 = torch.zeros((1, 1, 2 * 5 + 1, 2 * 5 + 1)).cuda()
d_k6 = torch.zeros((1, 1, 2 * 6 + 1, 2 * 6 + 1)).cuda()
d_k7 = torch.zeros((1, 1, 2 * 7 + 1, 2 * 7 + 1)).cuda()
d_k8 = torch.zeros((1, 1, 2 * 8 + 1, 2 * 8 + 1)).cuda()
d_k9 = torch.zeros((1, 1, 2 * 9 + 1, 2 * 9 + 1)).cuda()
d_ks = {
1: d_k1, 2: d_k2, 3: d_k3, 4: d_k4,
5: d_k5, 6: d_k6, 7: d_k7, 8: d_k8, 9: d_k9}
for k, v in d_ks.items():
v[:, :, k, k] = 1
for i in range(k):
v = dilation(v, selem_dilation)
d_ks[k] = v.squeeze(0).squeeze(0)
print(f'dilation kernel at {
k}:\n\n{
d_ks[k]}')
The appearance of these convolution kernels is roughly as follows , And so on 
边栏推荐
- PDK process library installation -csmc
- Leetcode 701 insertion operation in binary search tree -- recursive method and iterative method
- ArcGIS应用基础4 专题图的制作
- Anti shake and throttling are easy to understand
- Wib3.0 leapfrogging, in leapfrogging (ง • ̀_•́) ง
- Clear floating mode
- Li Chuang EDA learning notes 12: common PCB board layout constraint principles
- 养了只小猫咪
- Migrate Infones to stm32
- Node 之 nvm 下载、安装、使用,以及node 、nrm 的相关使用
猜你喜欢

Report on the competition status and investment decision recommendations of Guangxi hospital industry in China from 2022 to 2028

Clear floating mode

PDK工艺库安装-CSMC

ArcGIS应用基础4 专题图的制作

Huawei BFD configuration specification

養了只小猫咪

C language bubble sort

初识数据库

The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower

清除浮动的方式
随机推荐
The difference and usage between continue and break
How to use PHP string query function
[SQL Server Express Way] - authentification et création et gestion de comptes utilisateurs
【经验】UltralSO制作启动盘时报错:磁盘/映像容量太小
Pytorch代码注意的细节,容易敲错的地方
入侵检测领域数据集总结
Download, install and use NVM of node, and related use of node and NRM
Analysis of grammar elements in turtle Library
[Baiwen smart home] first day of the course_ Learn Embedded and understand the development mode of bare metal and RTOS
Market development prospect and investment risk assessment report of China's humidity sensor industry from 2022 to 2028
Practice sharing: how to safely and quickly migrate from CentOS to openeuler
Redis message queue
A master in the field of software architecture -- Reading Notes of the beauty of Architecture
Huawei BFD configuration specification
H3C V7 switch configuration IRF
Bit operation rules
Installation de la Bibliothèque de processus PDK - csmc
【论文阅读】NFlowJS:基于鲁棒学习的合成负数据密集异常检测
YYGH-11-定时统计
华为路由器如何配置静态路由