xttmp 2.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- xttmp/__init__.py +1 -0
- xttmp/api/__init__.py +5 -0
- xttmp/api/evaluate.py +163 -0
- xttmp/api/get_visualize_handle.py +29 -0
- xttmp/api/instancing_model.py +35 -0
- xttmp/core/__init__.py +0 -0
- xttmp/core/apgstmd_core.py +188 -0
- xttmp/core/apgstmdv2_core.py +79 -0
- xttmp/core/base_core.py +36 -0
- xttmp/core/dstmd_core.py +213 -0
- xttmp/core/estmd_backbone.py +110 -0
- xttmp/core/estmd_core.py +356 -0
- xttmp/core/feedbackstmd_core.py +61 -0
- xttmp/core/fracstmd_core.py +98 -0
- xttmp/core/fstmd_core.py +15 -0
- xttmp/core/fstmdv2_core.py +42 -0
- xttmp/core/haarstmd_core.py +140 -0
- xttmp/core/math_operator.py +307 -0
- xttmp/core/stfeedbackstmd_core.py +233 -0
- xttmp/core/stmdplus_core.py +187 -0
- xttmp/core/stmdplusv2_core.py +82 -0
- xttmp/core/vstmd_core.py +420 -0
- xttmp/demo/evaluate_model.py +92 -0
- xttmp/demo/inference_gui.py +148 -0
- xttmp/demo/inference_gui_single_process.py +134 -0
- xttmp/demo/inference_image_stream.py +67 -0
- xttmp/demo/inference_video.py +66 -0
- xttmp/main.py +14 -0
- xttmp/model/__init__.py +13 -0
- xttmp/model/backbone.py +514 -0
- xttmp/model/facilitated_model.py +230 -0
- xttmp/model/feedback_model.py +271 -0
- xttmp/model/haarstmd.py +61 -0
- xttmp/model/vstmd.py +457 -0
- xttmp/util/__init__.py +0 -0
- xttmp/util/compute_module.py +402 -0
- xttmp/util/create_kernel.py +363 -0
- xttmp/util/evaluate_module.py +697 -0
- xttmp/util/iostream.py +660 -0
- xttmp-2.3.0.dist-info/METADATA +85 -0
- xttmp-2.3.0.dist-info/RECORD +45 -0
- xttmp-2.3.0.dist-info/WHEEL +5 -0
- xttmp-2.3.0.dist-info/entry_points.txt +2 -0
- xttmp-2.3.0.dist-info/licenses/LICENSE +201 -0
- xttmp-2.3.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import torch
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def create_2d_gaussian_kernel(size, sigma):
|
|
8
|
+
# 处理参数 (简化防御性编程,假设输入已经是合法的 int 或 tuple)
|
|
9
|
+
sy, sx = (size, size) if isinstance(size, int) else size
|
|
10
|
+
sig_y, sig_x = (sigma, sigma) if isinstance(sigma, (int, float)) else sigma
|
|
11
|
+
|
|
12
|
+
# 生成 1D 坐标
|
|
13
|
+
y = torch.arange(sy, dtype=torch.float32) - sy // 2
|
|
14
|
+
x = torch.arange(sx, dtype=torch.float32) - sx // 2
|
|
15
|
+
|
|
16
|
+
# 生成 2D 网格坐标 (yy 和 xx 都是 size 形状的矩阵)
|
|
17
|
+
yy, xx = torch.meshgrid(y, x, indexing='ij')
|
|
18
|
+
|
|
19
|
+
# 直接将 2D 坐标代入二维高斯公式(一眼就能看懂的数学表达)
|
|
20
|
+
kernel = torch.exp(-(xx**2 / (2 * sig_x**2) + yy**2 / (2 * sig_y**2)))
|
|
21
|
+
|
|
22
|
+
# 归一化并调整形状
|
|
23
|
+
kernel /= kernel.sum()
|
|
24
|
+
return kernel.view(1, 1, sy, sx)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def create_gamma_kernel(order, tau, length):
|
|
28
|
+
t = torch.arange(length, dtype=torch.float32)
|
|
29
|
+
|
|
30
|
+
# 避免 t=0 时 log(0) 报错,加一个极小的值 eps
|
|
31
|
+
t_safe = torch.clamp(t, min=1e-7)
|
|
32
|
+
|
|
33
|
+
fact = math.factorial(order - 1)
|
|
34
|
+
|
|
35
|
+
# 计算对数域下的结果 (Log Domain)
|
|
36
|
+
# ln(kernel) = order * ln(order * t / tau) - (order * t / tau) - ln(tau * fact)
|
|
37
|
+
log_kernel = (order * torch.log(order * t_safe / tau)
|
|
38
|
+
- (order * t_safe / tau)
|
|
39
|
+
- math.log(tau * float(fact)))
|
|
40
|
+
|
|
41
|
+
# 还原回线性域
|
|
42
|
+
kernel = torch.exp(log_kernel)
|
|
43
|
+
|
|
44
|
+
# 修正 t=0 时的真实值
|
|
45
|
+
kernel[0] = 0.0
|
|
46
|
+
|
|
47
|
+
return kernel.view(-1, 1, 1, 1)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def create_spatial_inhibition_kernel(kernel_size=15,
|
|
51
|
+
sigma1=1.5,
|
|
52
|
+
sigma2=3,
|
|
53
|
+
e=1.,
|
|
54
|
+
rho=0,
|
|
55
|
+
A=1,
|
|
56
|
+
B=3):
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
coords = torch.arange(kernel_size, dtype=torch.float32) - kernel_size // 2
|
|
60
|
+
y, x = torch.meshgrid(coords, coords, indexing='ij')
|
|
61
|
+
|
|
62
|
+
# 计算欧式距离矩阵
|
|
63
|
+
r = torch.sqrt(x**2 + y**2)
|
|
64
|
+
|
|
65
|
+
# 计算双高斯分布 (Difference of Gaussians 的变体)
|
|
66
|
+
# g1 为中心兴奋 (Center),g2 为周边抑制 (Surround)
|
|
67
|
+
g1 = torch.exp(-(r**2) / (2 * sigma1**2)) / (2 * torch.pi * sigma1**2)
|
|
68
|
+
g2 = torch.exp(-(r**2) / (2 * sigma2**2)) / (2 * torch.pi * sigma2**2)
|
|
69
|
+
|
|
70
|
+
g = g1 - e * g2 - rho
|
|
71
|
+
|
|
72
|
+
kernel = A * g.clamp(min=0) + B * g.clamp(max=0)
|
|
73
|
+
|
|
74
|
+
return kernel / kernel.max()
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def create_direction_inhi_kernel(KernelSize=8, Sigma1=1.5, Sigma2=3.0):
|
|
78
|
+
"""
|
|
79
|
+
Function Description:
|
|
80
|
+
This function generates lateral inhibition kernels along the Theta direction using PyTorch.
|
|
81
|
+
We adopt a one-dimensional DoG as the lateral inhibition kernel function here.
|
|
82
|
+
"""
|
|
83
|
+
# 确保输入参数为浮点数张量,以便进行数学运算
|
|
84
|
+
s1 = torch.tensor(Sigma1, dtype=torch.float32)
|
|
85
|
+
s2 = torch.tensor(Sigma2, dtype=torch.float32)
|
|
86
|
+
|
|
87
|
+
# Sampling for DoG
|
|
88
|
+
zero_point_factor = (torch.log(s2 / s1) * 2 * (s1**2) * (s2**2)) / (s2**2 - s1**2)
|
|
89
|
+
Zero_Point_DoG_X1 = -torch.sqrt(zero_point_factor)
|
|
90
|
+
Zero_Point_DoG_X2 = -Zero_Point_DoG_X1
|
|
91
|
+
|
|
92
|
+
Min_Point_DoG_X1 = -torch.sqrt(3 * zero_point_factor)
|
|
93
|
+
Min_Point_DoG_X2 = -Min_Point_DoG_X1
|
|
94
|
+
|
|
95
|
+
if KernelSize % 2 == 0:
|
|
96
|
+
KernelSize += 1
|
|
97
|
+
|
|
98
|
+
Half_Kernel_Size = (KernelSize - 1) // 2
|
|
99
|
+
Quarter_Kernel_Size = (KernelSize - 1) // 4
|
|
100
|
+
|
|
101
|
+
Center_Range_DoG = Zero_Point_DoG_X2 - Zero_Point_DoG_X1
|
|
102
|
+
Center_Step = Center_Range_DoG / Half_Kernel_Size
|
|
103
|
+
|
|
104
|
+
Surround_Range_DoG = Min_Point_DoG_X2 - Zero_Point_DoG_X2
|
|
105
|
+
Surround_Step = 2 * Surround_Range_DoG / Quarter_Kernel_Size
|
|
106
|
+
|
|
107
|
+
# 使用 torch.arange 替换 np.arange
|
|
108
|
+
# 注意:为了让步长乘法正确应用,arange 生成的序列需要显式指定为 float 类型
|
|
109
|
+
X_Smaller = Zero_Point_DoG_X1 - torch.arange(Quarter_Kernel_Size, 0, -1, dtype=torch.float32) * Surround_Step
|
|
110
|
+
X_Larger = Zero_Point_DoG_X2 + torch.arange(1, Quarter_Kernel_Size + 1, 1, dtype=torch.float32) * Surround_Step
|
|
111
|
+
X_Center = Zero_Point_DoG_X1 + torch.arange(0, Half_Kernel_Size + 1, dtype=torch.float32) * Center_Step
|
|
112
|
+
|
|
113
|
+
# 使用 torch.cat 替换 np.concatenate
|
|
114
|
+
X = torch.cat((X_Smaller, X_Center, X_Larger))
|
|
115
|
+
|
|
116
|
+
# 计算高斯分布
|
|
117
|
+
pi_tensor = torch.tensor(torch.pi)
|
|
118
|
+
Gauss1 = torch.exp(-(X**2) / (2 * s1**2)) / (2 * pi_tensor * s1**2)
|
|
119
|
+
Gauss2 = torch.exp(-(X**2) / (2 * s2**2)) / (2 * pi_tensor * s2**2)
|
|
120
|
+
Inhibition_Kernel = Gauss1 - Gauss2
|
|
121
|
+
|
|
122
|
+
# 阈值置零
|
|
123
|
+
Inhibition_Kernel[torch.abs(Inhibition_Kernel) < 1e-4] = 0
|
|
124
|
+
|
|
125
|
+
# 使用 torch.reshape 改变形状
|
|
126
|
+
directionalInhiKernel = torch.reshape(Inhibition_Kernel, (1, 1, KernelSize))
|
|
127
|
+
|
|
128
|
+
return directionalInhiKernel
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def create_T1_kernels(filterNum=4,
|
|
132
|
+
alpha=3.0,
|
|
133
|
+
eta=1.5,
|
|
134
|
+
filterSize=11,
|
|
135
|
+
device='cpu'):
|
|
136
|
+
"""
|
|
137
|
+
Generate T1 kernels (Difference of Gaussians) using pure PyTorch.
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
torch.Tensor: A tensor of shape (filterNum, filterSize, filterSize)
|
|
141
|
+
"""
|
|
142
|
+
# If the filter size is even, force it to be odd
|
|
143
|
+
if filterSize % 2 == 0:
|
|
144
|
+
filterSize += 1
|
|
145
|
+
|
|
146
|
+
# 1. Compute angles for each filter
|
|
147
|
+
# 形状: (filterNum,) -> 例如 [0, pi/4, pi/2, 3pi/4]
|
|
148
|
+
Theta = torch.arange(filterNum, dtype=torch.float32, device=device) * torch.pi / filterNum
|
|
149
|
+
|
|
150
|
+
# 2. Generate coordinates
|
|
151
|
+
r = filterSize // 2
|
|
152
|
+
x_coords = torch.arange(-r, r + 1, dtype=torch.float32, device=device)
|
|
153
|
+
y_coords = torch.arange(r, -r - 1, -1, dtype=torch.float32, device=device)
|
|
154
|
+
|
|
155
|
+
# indexing='xy' 保证了与 numpy.meshgrid 默认行为完全一致
|
|
156
|
+
X, Y = torch.meshgrid(x_coords, y_coords, indexing='xy')
|
|
157
|
+
|
|
158
|
+
# 3. 维度扩展以支持批量(向量化)计算
|
|
159
|
+
# 将 X, Y 扩展为 (1, filterSize, filterSize)
|
|
160
|
+
X = X.unsqueeze(0)
|
|
161
|
+
Y = Y.unsqueeze(0)
|
|
162
|
+
|
|
163
|
+
# 将 Theta 扩展为 (filterNum, 1, 1)
|
|
164
|
+
Theta = Theta.view(-1, 1, 1)
|
|
165
|
+
|
|
166
|
+
# 4. 向量化计算偏移量 (X1, Y1, X2, Y2)
|
|
167
|
+
# 利用广播机制,这里会生成形状为 (filterNum, filterSize, filterSize) 的张量
|
|
168
|
+
cos_theta = torch.cos(Theta)
|
|
169
|
+
sin_theta = torch.sin(Theta)
|
|
170
|
+
|
|
171
|
+
X1 = X - alpha * cos_theta
|
|
172
|
+
Y1 = Y - alpha * sin_theta
|
|
173
|
+
|
|
174
|
+
X2 = X + alpha * cos_theta
|
|
175
|
+
Y2 = Y + alpha * sin_theta
|
|
176
|
+
|
|
177
|
+
# 5. 生成高斯分布
|
|
178
|
+
coeff = 1 / (2 * torch.pi * eta**2)
|
|
179
|
+
gauss1 = coeff * torch.exp(-(X1**2 + Y1**2) / (2 * eta**2))
|
|
180
|
+
gauss2 = coeff * torch.exp(-(X2**2 + Y2**2) / (2 * eta**2))
|
|
181
|
+
|
|
182
|
+
# 6. 计算差值 (最终的滤波器)
|
|
183
|
+
# 形状: (filterNum, filterSize, filterSize)
|
|
184
|
+
dictKernel = gauss1 - gauss2
|
|
185
|
+
|
|
186
|
+
# 如果你坚持需要返回 list,可以取消下面这行的注释:
|
|
187
|
+
# return list(dictKernel)
|
|
188
|
+
|
|
189
|
+
return dictKernel.unsqueeze(1) # 返回形状为 (filterNum, 1, filterSize, filterSize) 的张量
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def create_fracdiff_kernel(alpha=0.8, wide=3):
|
|
193
|
+
"""
|
|
194
|
+
Generates a fractional difference kernel.
|
|
195
|
+
|
|
196
|
+
Parameters:
|
|
197
|
+
- alpha: The fractional difference parameter.
|
|
198
|
+
- wide: The width of the kernel.
|
|
199
|
+
|
|
200
|
+
Returns:
|
|
201
|
+
- frackernel: The fractional difference kernel.
|
|
202
|
+
"""
|
|
203
|
+
# Ensure the width is at least 2
|
|
204
|
+
if wide < 2:
|
|
205
|
+
wide = 2
|
|
206
|
+
|
|
207
|
+
# Initialize the kernel
|
|
208
|
+
frackernel = torch.zeros(wide, dtype=torch.float32)
|
|
209
|
+
|
|
210
|
+
# Generate the kernel based on alpha
|
|
211
|
+
if alpha == 1:
|
|
212
|
+
frackernel[0] = 1
|
|
213
|
+
elif 0 < alpha < 1:
|
|
214
|
+
t_list = torch.arange(wide)
|
|
215
|
+
frackernel = torch.exp(-alpha * t_list / (1 - alpha)) / (1 - alpha)
|
|
216
|
+
|
|
217
|
+
# Normalize the kernel
|
|
218
|
+
sum_kernel = torch.sum(frackernel) # 1/M(\alpha)
|
|
219
|
+
frackernel = frackernel / sum_kernel
|
|
220
|
+
frackernel[frackernel < 1e-16] = 0
|
|
221
|
+
else:
|
|
222
|
+
raise ValueError("Alpha must be in the interval (0,1].")
|
|
223
|
+
|
|
224
|
+
return frackernel
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def create_attention_kernel(kernel_size=17,
|
|
228
|
+
zeta=[2, 2.5, 3, 3.5],
|
|
229
|
+
theta=[0, math.pi/4, math.pi/2, math.pi*3/4],
|
|
230
|
+
device='cpu',
|
|
231
|
+
dtype=torch.float32):
|
|
232
|
+
"""
|
|
233
|
+
Creates attention kernels using PyTorch.
|
|
234
|
+
|
|
235
|
+
Parameters:
|
|
236
|
+
- kernel_size: Size of the kernel.
|
|
237
|
+
- zeta: List of zeta values.
|
|
238
|
+
- theta: List of theta values.
|
|
239
|
+
- device: Target device for the tensors (e.g., 'cpu', 'cuda').
|
|
240
|
+
- dtype: Data type for the tensors.
|
|
241
|
+
|
|
242
|
+
Returns:
|
|
243
|
+
- attention_kernel: 2D list containing attention kernels as PyTorch tensors.
|
|
244
|
+
"""
|
|
245
|
+
|
|
246
|
+
# 调整 kernel size(如果是偶数则加 1)
|
|
247
|
+
if kernel_size % 2 == 0:
|
|
248
|
+
kernel_size += 1
|
|
249
|
+
|
|
250
|
+
# 初始化存储 attention kernels 的二维列表
|
|
251
|
+
r = len(zeta)
|
|
252
|
+
s = len(theta)
|
|
253
|
+
attention_kernel = [[None] * s for _ in range(r)]
|
|
254
|
+
|
|
255
|
+
# 计算 kernel 中心点
|
|
256
|
+
center = (kernel_size - 1) / 2
|
|
257
|
+
|
|
258
|
+
# 生成网格坐标 (注意 dtype 和 device 的传递)
|
|
259
|
+
x = torch.arange(kernel_size, dtype=dtype, device=device) - center
|
|
260
|
+
y = torch.arange(kernel_size, 0, -1, dtype=dtype, device=device) - center
|
|
261
|
+
|
|
262
|
+
# PyTorch 的 meshgrid 需要明确指定 indexing='xy' 以对齐 NumPy 的默认行为
|
|
263
|
+
shift_x, shift_y = torch.meshgrid(x, y, indexing='xy')
|
|
264
|
+
|
|
265
|
+
# 为每种 Zeta 和 Theta 的组合生成 attention kernels
|
|
266
|
+
for i in range(r):
|
|
267
|
+
for j in range(s):
|
|
268
|
+
# 将标量转换为 float 进行计算
|
|
269
|
+
z_val = float(zeta[i])
|
|
270
|
+
t_val = float(theta[j])
|
|
271
|
+
|
|
272
|
+
# 预计算三角函数以提升效率
|
|
273
|
+
cos_val = math.cos(t_val + math.pi / 2)
|
|
274
|
+
sin_val = math.sin(t_val + math.pi / 2)
|
|
275
|
+
|
|
276
|
+
# 生成核公式
|
|
277
|
+
term1 = 2 / math.pi / (z_val ** 4)
|
|
278
|
+
term2 = z_val ** 2 - (shift_x * cos_val + shift_y * sin_val) ** 2
|
|
279
|
+
term3 = torch.exp(-(shift_x ** 2 + shift_y ** 2) / (2 * z_val ** 2))
|
|
280
|
+
|
|
281
|
+
attention_kernel_with_ij = term1 * term2 * term3
|
|
282
|
+
|
|
283
|
+
# 阈值过滤 (使用 torch.abs)
|
|
284
|
+
attention_kernel_with_ij[torch.abs(attention_kernel_with_ij) < 1e-4] = 0
|
|
285
|
+
|
|
286
|
+
# 翻转卷积核 (对应 NumPy 中的 axis=0 和 axis=1)
|
|
287
|
+
attention_kernel_with_ij = torch.flip(attention_kernel_with_ij, dims=[0, 1])
|
|
288
|
+
|
|
289
|
+
attention_kernel[i][j] = attention_kernel_with_ij
|
|
290
|
+
|
|
291
|
+
return attention_kernel
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def create_prediction_kernel(Vel=0.25,
|
|
295
|
+
Delta_t=25,
|
|
296
|
+
filter_size=25,
|
|
297
|
+
FilterNum=8,
|
|
298
|
+
zeta=2,
|
|
299
|
+
eta=2.5,
|
|
300
|
+
device='cpu',
|
|
301
|
+
dtype=torch.float32):
|
|
302
|
+
"""
|
|
303
|
+
Creates prediction kernels for motion detection using PyTorch.
|
|
304
|
+
|
|
305
|
+
Parameters:
|
|
306
|
+
- Vel: Velocity of the moving object.
|
|
307
|
+
- Delta_t: Time interval.
|
|
308
|
+
- filter_size: Size of the filter.
|
|
309
|
+
- FilterNum: Number of filters.
|
|
310
|
+
- zeta: Zeta parameter.
|
|
311
|
+
- eta: Eta parameter.
|
|
312
|
+
- device: Target device for the tensors (e.g., 'cpu', 'cuda').
|
|
313
|
+
- dtype: Data type for the tensors.
|
|
314
|
+
|
|
315
|
+
Returns:
|
|
316
|
+
- PredictionKernal: List containing prediction kernels as PyTorch tensors.
|
|
317
|
+
"""
|
|
318
|
+
|
|
319
|
+
# 初始化存储 prediction kernels 的列表
|
|
320
|
+
PredictionKernal = []
|
|
321
|
+
|
|
322
|
+
# 计算中心点
|
|
323
|
+
Center = (filter_size - 1) / 2
|
|
324
|
+
|
|
325
|
+
# 生成网格坐标 (与 NumPy 的 meshgrid 对齐)
|
|
326
|
+
x = torch.arange(filter_size, dtype=dtype, device=device) - Center
|
|
327
|
+
y = torch.arange(filter_size, 0, -1, dtype=dtype, device=device) - Center
|
|
328
|
+
ShiftX, ShiftY = torch.meshgrid(x, y, indexing='xy')
|
|
329
|
+
|
|
330
|
+
# 计算角度 (注意 torch.atan2 的参数顺序与 np.arctan2 一致,都是 y, x)
|
|
331
|
+
fai = torch.atan2(ShiftY, ShiftX)
|
|
332
|
+
|
|
333
|
+
# 计算 Delta X 和 Delta Y
|
|
334
|
+
Delta_X = Vel * Delta_t * torch.cos(fai)
|
|
335
|
+
Delta_Y = Vel * Delta_t * torch.sin(fai)
|
|
336
|
+
|
|
337
|
+
# 生成每个方向的 prediction kernels
|
|
338
|
+
for idx in range(FilterNum):
|
|
339
|
+
# 严格遵循原代码逻辑:(idx - 1)
|
|
340
|
+
theta = (idx - 1) * 2 * torch.pi / FilterNum
|
|
341
|
+
|
|
342
|
+
# 计算指数项
|
|
343
|
+
PredictionKernalWithIdx = torch.exp(
|
|
344
|
+
-((ShiftX - Delta_X) ** 2 + (ShiftY - Delta_Y) ** 2) / (2 * zeta ** 2)
|
|
345
|
+
+ eta * torch.cos(fai - theta)
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
# 第一次归一化
|
|
349
|
+
PredictionKernalWithIdx = PredictionKernalWithIdx / torch.sum(PredictionKernalWithIdx)
|
|
350
|
+
|
|
351
|
+
# 阈值过滤以加速计算
|
|
352
|
+
PredictionKernalWithIdx[PredictionKernalWithIdx < 5e-4] = 0
|
|
353
|
+
|
|
354
|
+
# 第二次归一化
|
|
355
|
+
PredictionKernalWithIdx /= torch.sum(PredictionKernalWithIdx)
|
|
356
|
+
|
|
357
|
+
# 翻转卷积核 (对应 np.flip axis=0 和 axis=1)
|
|
358
|
+
PredictionKernalWithIdx = torch.flip(PredictionKernalWithIdx, dims=[0, 1])
|
|
359
|
+
|
|
360
|
+
PredictionKernal.append(PredictionKernalWithIdx)
|
|
361
|
+
|
|
362
|
+
return PredictionKernal
|
|
363
|
+
|