当前位置:网站首页>[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 
边栏推荐
- Clear floating mode
- What preparations should be made for website server migration?
- What is independent IP and how about independent IP host?
- continue和break的区别与用法
- Network protocol model
- AUTOSAR从入门到精通番外篇(十)-嵌入式S19文件解析
- Station B, Master Liu Er - back propagation
- Hongliao Technology: Liu qiangdong's "heavy hand"
- wib3.0 跨越,在跨越(ง •̀_•́)ง
- H3C firewall rbm+vrrp networking configuration
猜你喜欢

The difference and usage between continue and break

Analysis report on development trends and investment planning of China's methanol industry from 2022 to 2028

Practice sharing: how to safely and quickly migrate from CentOS to openeuler

P2802 go home

网站进行服务器迁移前应做好哪些准备?
![[Tang Laoshi] C -- encapsulation: classes and objects](/img/4e/30d2d4652ea2d4cd5fa7cbbb795863.jpg)
[Tang Laoshi] C -- encapsulation: classes and objects
![[Jiudu OJ 07] folding basket](/img/a7/e394f32cf7f02468988addad67674b.jpg)
[Jiudu OJ 07] folding basket

【课程笔记】编译原理

局域网同一个网段通信过程

Web服务连接器:Servlet
随机推荐
Game push image / table /cv/nlp, multi-threaded start
How to download GB files from Google cloud hard disk
网络协议模型
类和对象(一)this指针详解
Migrate Infones to stm32
[Jiudu OJ 07] folding basket
Download, install and use NVM of node, and related use of node and NRM
Yunxiaoduo software internal test distribution test platform description document
First knowledge database
B站刘二大人-多元逻辑回归 Lecture 7
Analysis report on development trends and investment planning of China's methanol industry from 2022 to 2028
Station B, Mr. Liu Er - multiple logistic regression, structure 7
H3C V7 switch configuration IRF
养了只小猫咪
Hongliao Technology: how to quickly improve Tiktok store
Pay attention to the details of pytoch code, and it is easy to make mistakes
巨杉数据库再次亮相金交会,共建数字经济新时代
[Tang Laoshi] C -- encapsulation: classes and objects
AUTOSAR from getting started to becoming proficient (10) - embedded S19 file analysis
PDK工艺库安装-CSMC