下面这个函数可以在GPU上运行吗?能使用cuda加速吗?函数是代码中的一部分,只分析原因和结果,不用写代码。def ExtractPIIFDFeatureOfObbAnchors(self, obbrois, imgpath):
"""对一张图片提取PIIFD特征
Args:
obbrois(list[Tensor(H*W,5)]):5个特征层的旋转锚框
imgpath(str):原图的路径
Returns:
imgpiifdlist[list[Tensor(batch,5,H,W)]]:5个特征层的piifd张量
"""
start_time = datetime.now()
image = cv2.imread(imgpath)
# 定义存储该图片5个特征层对应的piifd特征向量的存储列表
imgpiifdlist = []
# 读取视觉词典
mat_file = 'BOF/vocabulary_256.mat'
data = scipy.io.loadmat(mat_file)
vocab = data.get('vocabulary').astype('float32')
# with open('BOF/vocabn500s4v128.pkl','rb') as f:
# vocab = pickle.load(f)
# 循环取出每一个特征层处理
for roisall in obbrois:
# 定义该特征层锚框对应感兴趣区域的piifd特征向量存储列表
roispiifdlist = []
# 定义piifd特征的长度,包括piifd描述子(256)+全局特征(8)
obb_feats_len = 256 + 8
print('....................Start calculate one feature map .....................')
for i in range(roisall.shape[0]):
RegOfROI = roisall[i].cpu()
# print('Calculating NO ', str(i), 'roi')
# 1. 根据roi坐标扩展旋转框,返回扩充后的新的roi
expansion = 5
ExpandRegOfROI = self.expand_rotated_rect(RegOfROI, expansion)
# 2. 对扩展前后的roi分别进行提取矩形框
rotated = self.GetRotatedImg(RegOfROI, image)
rotated_pad = self.GetRotatedImg(ExpandRegOfROI, image)
# rotated_pad = np.pad(rotated,((5, 5), (5, 5), (0, 0)), mode='edge')
# 保存裁剪后的图像
# cv2.imwrite('rotated.jpg', rotated)
# cv2.imwrite('rotated_pad.jpg',rotated_pad)
# img = cv2.imread(r'D:\MMRotate_LiYangFan\ship_detection\tools\cropped_image.jpg')
# 将原始图像转换为灰度
gray_image = cv2.cvtColor(rotated, cv2.COLOR_BGR2GRAY)
gray_image_pad = cv2.cvtColor(rotated_pad, cv2.COLOR_BGR2GRAY)
# 转为双精度浮点型
image1_gray_np = np.array(gray_image)
image1_gray_pad_np = np.array(gray_image_pad)
image1_double = image1_gray_pad_np.astype(np.float64)
# 3. 对扩展前的roi进行Fast关键点提取
corners_FAST1 = self.FastPointsDetect(image1_gray_np)
# 4. 将原roi坐标转换至新的roi区域内
adjusted_keypoints = [(x + expansion, y + expansion) for x, y in corners_FAST1]
adjusted_keypoints = np.array(adjusted_keypoints)
# 5. 将扩展后的roi和新的坐标往后传
obb_feats = None
if adjusted_keypoints.size == 0:
# 该锚框所在图像区域没有检出关键点
obb_feats = torch.zeros(1, obb_feats_len, dtype=torch.float32).cuda()
# print('#####No Points#####')
else:
# 该锚框所在区域检出关键点,则进行复杂网络演化进一步得到筛选后的关键点,利用筛选后的关键点求对应的PIIFD描述子,将PIIFD描述子与
# 复杂网络得到的全局特征结合构成认知特征
# 定义复杂网络的常量
Versionf = 1 # 版本
Num_evolution = 2 # 演化次数
# start_complexNet_time = datetime.now()
# 提取图像经过复杂网络演化的全局特征、局部特征、图中点的坐标
global_features_all, local_features_all, graph_pos = FeatureExt_CN(adjusted_keypoints,Num_evolution, Versionf,gray_image_pad)
# end_complexNet_time = datetime.now()
# print('#####Complete one roi complexNet : ',(end_complexNet_time - start_complexNet_time),'######')
# 经过复杂网络演化之后,关键点没有了
if global_features_all == None and local_features_all == None:
obb_feats = torch.zeros(1, obb_feats_len, dtype=torch.float32).cuda()
else:
# 定义MS-PIIFD算法常量
G_resize = 3 # 高斯金字塔的降采样单元
G_sigma = 1.6 # 高斯金字塔的模糊单元
numLayers = 4 # 高斯金字塔每组层数 4
numOctaves = 3 # 高斯金字塔的组数 3
# 选取复杂网络的第几层
Ti = 1
graph_pos_Ti = np.array(graph_pos[Ti])
graph_pos_Ti[:, 1] = image1_double.shape[0] - graph_pos_Ti[:, 1]
# 多尺度PIIFD
# sig = get_gaussian_scale(G_sigma, numLayers)
# descriptors_MS = get_multiscale_piifdm(image1_double, graph_pos_Ti, numOctaves, numLayers, G_resize,sig)
# 单尺度PIIFD
start_piifd_time = datetime.now()
descriptors = PIIFD_Descriptor(p=graph_pos_Ti, I=image1_double, octave=1, G_resize=G_resize)
descriptors = descriptors[:, 6:]
end_piifd_time = datetime.now()
print('~~~~~~~~~~~~Complete one roi piifd:', (end_piifd_time - start_piifd_time),'~~~~~~~~~~~')
# 度中心性 degreesCentrality:dict
local_features_Ti = local_features_all[Ti]
featureS_local_Ti_degreeCentrality = local_features_Ti['degreesCentrality']
featureS_local_Ti_degreeCentrality_values = []
for key, value in featureS_local_Ti_degreeCentrality.items():
if isinstance(value, float):
featureS_local_Ti_degreeCentrality_values.append(value)
featureS_local_Ti_degreeCentrality_values = np.array(featureS_local_Ti_degreeCentrality_values)
local_vocab_values = self.GetNormHist(vocab, descriptors,
featureS_local_Ti_degreeCentrality_values)
# 5. 将字典中的值取出并合并
global_features = global_features_all[Ti]
featureS_global_Ti_values = []
for key, value in global_features.items():
if isinstance(value, float):
featureS_global_Ti_values.append(value)
# 转换为 NumPy ndarray 并调整形状为 [1, N]
global_feature_values = np.array(featureS_global_Ti_values).reshape(1, -1)
obb_feats = np.concatenate((local_vocab_values, global_feature_values), axis=1)
obb_feats = torch.from_numpy(obb_feats).cuda().type(torch.cuda.FloatTensor)
# piifd_descriptor = piifdcreate(gray_image)
# print(piifd_descriptor.shape)
# piifdlen = piifd_descriptor.shape[1]
roispiifdlist.append(obb_feats)
# 获取每一个特征层的宽高
roishw = int(math.sqrt(roisall.shape[0]))
# 将该特征层piifd特征向量的列表改成H×W×piifd特征向量的形状(此处需要确定源特征成的形状以及传入参数的类型是否正确)
concatenated = torch.cat(roispiifdlist).view(roishw, roishw, obb_feats_len).permute(2, 0, 1).unsqueeze(0)
# 获得一张图片的5个特征层待拼接的piifd张量
imgpiifdlist.append(concatenated)
vob_end_time = datetime.now()
print('Complete one image get vobhist, use time', (vob_end_time - start_time))
return imgpiifdlist