当前位置:网站首页>[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 
边栏推荐
猜你喜欢

初识数据库

What is independent IP and how about independent IP host?

Cannot build artifact 'test Web: War expanded' because it is included into a circular depend solution

Game push image / table /cv/nlp, multi-threaded start

Hongliao Technology: Liu qiangdong's "heavy hand"
![[force buckle]43 String multiplication](/img/fd/de63e6185af4b6293e748aaf7cee29.jpg)
[force buckle]43 String multiplication

B站刘二大人-线性回归及梯度下降

P2802 go home
![[Jiudu OJ 08] simple search x](/img/a7/12a00c5d1db2deb064ff5f2e83dc58.jpg)
[Jiudu OJ 08] simple search x

How to use PHP string query function
随机推荐
Web Security (V) what is a session? Why do I need a session?
LAN communication process in the same network segment
How to download GB files from Google cloud hard disk
Jushan database appears again in the gold fair to jointly build a new era of digital economy
华为路由器如何配置静态路由
网站进行服务器迁移前应做好哪些准备?
What impact will frequent job hopping have on your career?
Novice entry SCM must understand those things
As3013 fire endurance test of cable distribution system
H3C S5820V2_ Upgrade method after stacking IRF2 of 5830v2 switch
Investment strategy discussion and market scale prediction report of China's solid state high power amplifier industry from 2022 to 2028
大型网站如何选择比较好的云主机服务商?
授予渔,从0开始搭建一个自己想要的网页
Download, install and use NVM of node, and related use of node and NRM
The digital economy has broken through the waves. Is Ltd a Web3.0 website with independent rights and interests?
Auto.js学习笔记17:基础监听事件和UI简单的点击事件操作
Raised a kitten
Auto. JS learning notes 17: basic listening events and UI simple click event operations
ArcGIS应用基础4 专题图的制作
查詢生產訂單中某個(些)工作中心對應的標准文本碼