使用LoFTR模型進行圖像配準、重疊區提取

LoFTR模型源自2021年CVPR提出的一篇論文LoFTR: Detector-Free Local Feature Matching with Transformers,其基于pytorch實現圖像配準,與基于superpoint+superglue的方法不同,
是一個端到端的圖像配準方法。與LoFTR官方庫相關的有loftr2onnx庫,整體來說loftr2onnx庫使用更方便,效果更好。但loftr2onnx轉出的onnx模型是有問題的,不能使用。

項目地址:https://github.com/zju3dv/LoFTR
項目地址2:https://github.com/oooooha/loftr2onnx
demo體驗:https://huggingface.co/spaces/kornia/Kornia-LoFTR

1、web demo體驗

訪問 https://huggingface.co/spaces/kornia/Kornia-LoFTR

點配準的效果如下所示,可以看到與sp+sg方法相比,點對的平行關系直觀上要好很多。
在這里插入圖片描述

2、使用LoFTR項目

2.1 下載代碼

打開https://github.com/zju3dv/LoFTR 下載代碼
在這里插入圖片描述

2.2 安裝依賴項

安裝項目使用:解壓代碼,然后在終端進入目錄,執行pip install -r .\requirements.txt
在這里插入圖片描述

2.3 下載模型

https://drive.google.com/drive/folders/1DOcOPZb3-5cWxLqn256AhwUVjBPifhuf 下載權重。如果需要訓練,可以下載訓練數據與從測試數據。
在這里插入圖片描述
將權重的壓縮文件解壓后放到項目根目錄下
在這里插入圖片描述

2.4 初步使用

將 https://hpg123.blog.csdn.net/article/details/124824892 中章節3的代碼(對應標題為 superpoint中read_img_as_tensor函數)保存為imgutils.py

from src.loftr import LoFTR, default_cfg
import torch
from imgutils import *
import time
# Initialize LoFTR
matcher = LoFTR(config=default_cfg)
matcher.load_state_dict(torch.load("weights/indoor_ds_new.ckpt")['state_dict'])
matcher = matcher.eval().cuda()p1=r'C:\Users\hpg\Pictures\t1.jpg'
p2=r'C:\Users\hpg\Pictures\t2.jpg'
t1,im1=read_img_as_tensor(p1,(384,384))
t2,im2=read_img_as_tensor(p2,(384,384))
batch = {'image0': t1, 'image1': t2}
# Inference
with torch.no_grad():matcher(batch)    # t0=time.time()times=10for i in range(times):matcher(batch)rt1=time.time()-t0rt1=rt1/timesmkpts0 = batch['mkpts0_f'].cpu().numpy()mkpts1 = batch['mkpts1_f'].cpu().numpy()mconf = batch['mconf'].cpu().numpy()print(f'運行時間:{rt1:.4f}',mkpts0.shape,mkpts1.shape,mconf)

代碼運行效果如下所示,可以看到一個圖片需要0.19s(筆記本,1060顯卡),換成臺式機3060顯卡,預計在0.05s左右一張圖

運行時間:0.1933 (32, 2) (32, 2) [0.22855578 0.21740437 0.34927088 0.28389925 0.27157754 0.269668280.22636016 0.22058277 0.20475665 0.20878278 0.22838292 0.254485850.27047077 0.34403533 0.22612476 0.2044811  0.26239234 0.327975540.2263804  0.26544347 0.3401669  0.39336586 0.3473139  0.282306940.23061718 0.23949552 0.46178365 0.3540019  0.5322925  0.272002370.26731068 0.39827508]

3、使用loftr2onnx庫進行配準

3.1 基本使用

也可以基于 https://github.com/oooooha/loftr2onnx 項目進行圖像配準
在這里插入圖片描述
使用代碼如下


from loftr_wrapper import LoFTRWrapper as LoFTR
import torch
from imgutils import *
import time
# Initialize LoFTR
matcher = LoFTR()
matcher.load_state_dict(torch.load("weights/indoor_ds_new.ckpt")['state_dict'])
matcher = matcher.eval().cuda()p1=r'C:\Users\hpg\Pictures\t1.jpg'
p2=r'C:\Users\hpg\Pictures\t2.jpg'
t1,im1=read_img_as_tensor(p1,(384,384))
t2,im2=read_img_as_tensor(p2,(384,384))
# Inference
with torch.no_grad():result=matcher(t1,t2)    # t0=time.time()times=10for i in range(times):result=matcher(t1,t2)rt1=time.time()-t0rt1=rt1/timesmkpts0 = result['keypoints0'].cpu().numpy()mkpts1 = result['keypoints1'].cpu().numpy()mconf = result['confidence'].cpu().numpy()print(f'運行時間:{rt1:.4f}',mkpts0.shape,mkpts1.shape,mconf)

代碼輸出如下所示,可以看到與LoFTR項目的輸出有所差異

運行時間:0.1925 (212, 2) (212, 2) [0.4566688  0.53420454 0.5319168  0.5320238  0.46744433 0.40682140.5363396  0.45674214 0.60001785 0.6576139  0.53006035 0.595909240.5725811  0.5505655  0.44364485 0.40315574 0.4293331  0.50609730.6550978  0.52451503 0.553644   0.63088214 0.6906601  0.616680740.4543735  0.4138872  0.4332955  0.47855106 0.60533136 0.67351430.7912271  0.7220486  0.75414115 0.75669855 0.60389113 0.403050660.71130437 0.6583284  0.5403245  0.5433615  0.40149704 0.66738440.4093839  0.5410701  0.51509964 0.42121148 0.68238974 0.552473960.5116625  0.8369319  0.53321654 0.5323315  0.5779519  0.647059260.43591025 0.40134645 0.4599252  0.46620858 0.6388375  0.83547580.515318   0.6521981  0.54744494 0.64528877 0.7466613  0.63595170.58179545 0.4587202  0.4856584  0.42029297 0.43322447 0.432207580.6896481  0.79645556 0.5817581  0.75245494 0.5786756  0.72515590.814531   0.49031648 0.46484298 0.54241467 0.5943087  0.72451150.6457875  0.8097793  0.7199513  0.49220178 0.5443373  0.40861040.5046131  0.7193697  0.6752727  0.41796637 0.5513792  0.70874180.7779165  0.75016826 0.68525094 0.58962977 0.6315668  0.49130850.56355244 0.41288543 0.52281946 0.42782715 0.43921712 0.52160180.5566503  0.78442967 0.6013023  0.42023212 0.43102428 0.615640640.40717542 0.49634054 0.45509326 0.4511342  0.41775596 0.558971760.56803375 0.6018254  0.71239305 0.44001386 0.43651453 0.69477330.8648205  0.4988858  0.40208712 0.71607304 0.9030141  0.55438260.49472648 0.5359598  0.74733096 0.6617334  0.7066015  0.7256770.43446922 0.5126569  0.52367914 0.45096788 0.4248741  0.432852750.723374   0.86523044 0.65740126 0.427191   0.4776224  0.48018260.4530296  0.4275035  0.527438   0.52301216 0.58992577 0.417273430.48609605 0.7365703  0.6339512  0.6379226  0.4489899  0.413250480.5010124  0.49238032 0.57079905 0.62783945 0.5092921  0.57263870.60590863 0.44714844 0.6284152  0.40801758 0.40126294 0.42214190.52245826 0.70989937 0.49206337 0.553483   0.4956581  0.41806970.6228596  0.6543849  0.7747963  0.61180156 0.60290194 0.54211940.6149054  0.48783877 0.40048426 0.47044232 0.40145218 0.423598560.68902797 0.44713116 0.84827214 0.48961237 0.6137104  0.77524260.7184252  0.71058017 0.47483382 0.7151901  0.78853625 0.669882540.7502565  0.42592585 0.49173304 0.4657402  0.59592575 0.428502770.4645101  0.5070625 ]

3.2 差異分析

1、這主要是loftr2onnx項目通過loftr_wrapper對LoFTR的forward流程進行了調整。

#!/usr/bin/env python
import copy
import os
import sys
from typing import Any, Dictimport torch
from einops.einops import rearrange_CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(_CURRENT_DIR, "LoFTR"))from loftr import LoFTR, default_cfgDEFAULT_CFG = copy.deepcopy(default_cfg)
DEFAULT_CFG["coarse"]["temp_bug_fix"] = Trueclass LoFTRWrapper(LoFTR):def __init__(self,config: Dict[str, Any] = DEFAULT_CFG,):LoFTR.__init__(self, config)def forward(self,image0: torch.Tensor,image1: torch.Tensor,) -> Dict[str, torch.Tensor]:data = {"image0": image0,"image1": image1,}del image0, image1data.update({"bs": data["image0"].size(0),"hw0_i": data["image0"].shape[2:],"hw1_i": data["image1"].shape[2:],})if data["hw0_i"] == data["hw1_i"]:  # faster & better BN convergencefeats_c, feats_f = self.backbone(torch.cat([data["image0"], data["image1"]], dim=0))(feat_c0, feat_c1), (feat_f0, feat_f1) = feats_c.split(data["bs"]), feats_f.split(data["bs"])else:  # handle different input shapes(feat_c0, feat_f0), (feat_c1, feat_f1) = self.backbone(data["image0"]), self.backbone(data["image1"])data.update({"hw0_c": feat_c0.shape[2:],"hw1_c": feat_c1.shape[2:],"hw0_f": feat_f0.shape[2:],"hw1_f": feat_f1.shape[2:],})# 2. coarse-level loftr module# add featmap with positional encoding, then flatten it to sequence [N, HW, C]feat_c0 = rearrange(self.pos_encoding(feat_c0), "n c h w -> n (h w) c")feat_c1 = rearrange(self.pos_encoding(feat_c1), "n c h w -> n (h w) c")mask_c0 = mask_c1 = None  # mask is useful in trainingif "mask0" in data:mask_c0, mask_c1 = data["mask0"].flatten(-2), data["mask1"].flatten(-2)feat_c0, feat_c1 = self.loftr_coarse(feat_c0, feat_c1, mask_c0, mask_c1)# 3. match coarse-levelself.coarse_matching(feat_c0, feat_c1, data, mask_c0=mask_c0, mask_c1=mask_c1)# 4. fine-level refinementfeat_f0_unfold, feat_f1_unfold = self.fine_preprocess(feat_f0, feat_f1, feat_c0, feat_c1, data)if feat_f0_unfold.size(0) != 0:  # at least one coarse level predictedfeat_f0_unfold, feat_f1_unfold = self.loftr_fine(feat_f0_unfold, feat_f1_unfold)# 5. match fine-levelself.fine_matching(feat_f0_unfold, feat_f1_unfold, data)rename_keys: Dict[str, str] = {"mkpts0_f": "keypoints0","mkpts1_f": "keypoints1","mconf": "confidence",}out: Dict[str, torch.Tensor] = {}for k, v in rename_keys.items():_d = data[k]if isinstance(_d, torch.Tensor):out[v] = _delse:raise TypeError(f"Expected torch.Tensor for item `{k}`. Gotcha {type(_d)}")del datareturn out

2、然后cfg或許有不同

loftr2onnx中的默認配置在loftr\utils\cvpr_ds_config.py中,如下所示。可以看到 _CN.MATCH_COARSE.THR與_CN.MATCH_COARSE.BORDER_RM 是做過修改的,與默認值不同

from yacs.config import CfgNode as CNdef lower_config(yacs_cfg):if not isinstance(yacs_cfg, CN):return yacs_cfgreturn {k.lower(): lower_config(v) for k, v in yacs_cfg.items()}_CN = CN()
_CN.BACKBONE_TYPE = 'ResNetFPN'
_CN.RESOLUTION = (8, 2)  # options: [(8, 2), (16, 4)]
_CN.FINE_WINDOW_SIZE = 5  # window_size in fine_level, must be odd
_CN.FINE_CONCAT_COARSE_FEAT = True# 1. LoFTR-backbone (local feature CNN) config
_CN.RESNETFPN = CN()
_CN.RESNETFPN.INITIAL_DIM = 128
_CN.RESNETFPN.BLOCK_DIMS = [128, 196, 256]  # s1, s2, s3# 2. LoFTR-coarse module config
_CN.COARSE = CN()
_CN.COARSE.D_MODEL = 256
_CN.COARSE.D_FFN = 256
_CN.COARSE.NHEAD = 8
_CN.COARSE.LAYER_NAMES = ['self', 'cross'] * 4
_CN.COARSE.ATTENTION = 'linear'  # options: ['linear', 'full']
_CN.COARSE.TEMP_BUG_FIX = False# 3. Coarse-Matching config
_CN.MATCH_COARSE = CN()
_CN.MATCH_COARSE.THR = 0.4  # thresh default=0.2
_CN.MATCH_COARSE.BORDER_RM = 4  # border default=2
_CN.MATCH_COARSE.MATCH_TYPE = 'dual_softmax'  # options: ['dual_softmax, 'sinkhorn']
_CN.MATCH_COARSE.DSMAX_TEMPERATURE = 0.1
_CN.MATCH_COARSE.SKH_ITERS = 3
_CN.MATCH_COARSE.SKH_INIT_BIN_SCORE = 1.0
_CN.MATCH_COARSE.SKH_PREFILTER = True
_CN.MATCH_COARSE.TRAIN_COARSE_PERCENT = 0.4  # training tricks: save GPU memory
_CN.MATCH_COARSE.TRAIN_PAD_NUM_GT_MIN = 200  # training tricks: avoid DDP deadlock# 4. LoFTR-fine module config
_CN.FINE = CN()
_CN.FINE.D_MODEL = 128
_CN.FINE.D_FFN = 128
_CN.FINE.NHEAD = 8
_CN.FINE.LAYER_NAMES = ['self', 'cross'] * 1
_CN.FINE.ATTENTION = 'linear'default_cfg = lower_config(_CN)

4、基于LoFTR提取重疊區域

4.1 使用LoFTR庫

這里的imgutils 與前文說明的有細微區別,打開https://blog.csdn.net/a486259/article/details/124824892 將章節1的代碼保存為imgutils.py即可

from src.loftr import LoFTR, default_cfg
import torch
from imgutils import *
import time
# Initialize LoFTR
matcher = LoFTR(config=default_cfg)
matcher.load_state_dict(torch.load("weights/indoor_ds_new.ckpt")['state_dict'])
matcher = matcher.eval().cuda()p1=r'C:\Users\hpg\Pictures\t1.jpg'
p2=r'C:\Users\hpg\Pictures\t2.jpg'
t1,im1=read_img_as_tensor_gray(p1,(384,384))
t2,im2=read_img_as_tensor_gray(p2,(384,384))
batch = {'image0': t1, 'image1': t2}
# Inference
with torch.no_grad():t0=time.time()times=1for i in range(times):matcher(batch)rt1=time.time()-t0rt1=rt1/timesmkpts0 = batch['mkpts0_f'].cpu().numpy()mkpts1 = batch['mkpts1_f'].cpu().numpy()confidence = batch['mconf'].cpu().numpy()print(f'運行時間:{rt1:.4f}',mkpts0.shape,mkpts1.shape)import cv2 as cv
pt_num = mkpts0.shape[0]
im_dst,im_res=im1,im2
img = np.zeros((max(im_dst.shape[0], im_res.shape[0]), im_dst.shape[1]+im_res.shape[1]+10,3))
img[:,:im_res.shape[0],]=im_dst
img[:,-im_res.shape[0]:]=im_res
img=img.astype(np.uint8)
match_threshold=0.6
for i in range(0, pt_num):if (confidence[i] > match_threshold):pt0 = mkpts0[i].to('cpu').numpy().astype(np.int32)pt1 = mkpts1[i].to('cpu').numpy().astype(np.int32)#cv.circle(img, (pt0[0], pt0[1]), 1, (0, 0, 255), 2)#cv.circle(img, (pt1[0], pt1[1]+650), (0, 0, 255), 2)cv.line(img, pt0, (pt1[0]+im_res.shape[0], pt1[1]), (0, 255, 0), 1)
myimshow( img,size=12)import cv2
def getGoodMatchPoint(mkpts0, mkpts1, confidence,  match_threshold:float=0.5):n = min(mkpts0.size(0), mkpts1.size(0))srcImage1_matchedKPs, srcImage2_matchedKPs=[],[]if (match_threshold > 1 or match_threshold < 0):print("match_threshold error!")for i in range(n):kp0 = mkpts0[i]kp1 = mkpts1[i]pt0=(kp0[0].item(),kp0[1].item());pt1=(kp1[0].item(),kp1[1].item());c = confidence[i].item();if (c > match_threshold):srcImage1_matchedKPs.append(pt0);srcImage2_matchedKPs.append(pt1);return np.array(srcImage1_matchedKPs),np.array(srcImage2_matchedKPs)
pts_src, pts_dst=getGoodMatchPoint(mkpts0, mkpts1, confidence)h1, status = cv2.findHomography(pts_src, pts_dst, cv.RANSAC, 8)
im_out1 = cv2.warpPerspective(im_dst, h1, (im_dst.shape[1],im_dst.shape[0]))
im_out2 = cv2.warpPerspective(im_res, h1, (im_dst.shape[1],im_dst.shape[0]),16)
#這里 im_res和im_out1是嚴格配準的狀態
myimshowsCL([im_dst,im_out1,im_res,im_out2],rows=2,cols=2, size=6)

在這里插入圖片描述
代碼運行報錯,因為匹配到的點太少了,無法計算轉化矩陣提取重疊區

4.2 使用loftr2onnx庫

這里的imgutils 與前文說明的有細微區別,打開https://blog.csdn.net/a486259/article/details/124824892 將章節1的代碼保存為imgutils.py即可

使用代碼如下


from loftr_wrapper import LoFTRWrapper as LoFTR
import torch
from imgutils import *
import time
# Initialize LoFTR
matcher = LoFTR()
matcher.load_state_dict(torch.load("weights/indoor_ds_new.ckpt")['state_dict'])
matcher = matcher.eval().cuda()p1=r'C:\Users\hpg\Pictures\t1.jpg'
p2=r'C:\Users\hpg\Pictures\t2.jpg'
t1,im1=read_img_as_tensor_gray(p1,(384,384))
t2,im2=read_img_as_tensor_gray(p2,(384,384))
# Inference
with torch.no_grad():#result=matcher(t1,t2)    # t0=time.time()times=1for i in range(times):result=matcher(t1,t2)rt1=time.time()-t0rt1=rt1/timesmkpts0 = result['keypoints0']#.cpu().numpy()mkpts1 = result['keypoints1']#.cpu().numpy()confidence = result['confidence']#.cpu().numpy()print(f'運行時間:{rt1:.4f}',mkpts0.shape,mkpts1.shape,confidence)import cv2 as cv
pt_num = mkpts0.shape[0]
im_dst,im_res=im1,im2
img = np.zeros((max(im_dst.shape[0], im_res.shape[0]), im_dst.shape[1]+im_res.shape[1]+10,3))
img[:,:im_res.shape[0],]=im_dst
img[:,-im_res.shape[0]:]=im_res
img=img.astype(np.uint8)
match_threshold=0.01
for i in range(0, pt_num):if (confidence[i] > match_threshold):pt0 = mkpts0[i].to('cpu').numpy().astype(np.int32)pt1 = mkpts1[i].to('cpu').numpy().astype(np.int32)#cv.circle(img, (pt0[0], pt0[1]), 1, (0, 0, 255), 2)#cv.circle(img, (pt1[0], pt1[1]+650), (0, 0, 255), 2)cv.line(img, tuple(pt0.tolist()), (pt1[0]+im_res.shape[0], pt1[1]), (0, 255, 0), 1)
myimshow( img,size=12)import cv2
def getGoodMatchPoint(mkpts0, mkpts1, confidence,  match_threshold:float=0.5):n = min(mkpts0.size(0), mkpts1.size(0))srcImage1_matchedKPs, srcImage2_matchedKPs=[],[]if (match_threshold > 1 or match_threshold < 0):print("match_threshold error!")for i in range(n):kp0 = mkpts0[i]kp1 = mkpts1[i]pt0=(kp0[0].item(),kp0[1].item());pt1=(kp1[0].item(),kp1[1].item());c = confidence[i].item();if (c > match_threshold):srcImage1_matchedKPs.append(pt0);srcImage2_matchedKPs.append(pt1);return np.array(srcImage1_matchedKPs),np.array(srcImage2_matchedKPs)
pts_src, pts_dst=getGoodMatchPoint(mkpts0, mkpts1, confidence)h1, status = cv2.findHomography(pts_src, pts_dst, cv.RANSAC, 4)
# im_dst=im_dst.astype(np.float32)/255
# im_res=im_res.astype(np.float32)/255
print(im_dst.shape,im_dst.dtype,im_dst.max(),im_res.shape,im_res.dtype,im_res.max(),h1)
im_out1 = cv2.warpPerspective(im_dst, h1, (im_dst.shape[1],im_dst.shape[0]))
im_out2 = cv2.warpPerspective(im_res, h1, (im_dst.shape[1],im_dst.shape[0]),16)
#這里 im_res和im_out1是嚴格配準的狀態
myimshowsCL([im_dst,im_out1,im_res,im_out2],rows=2,cols=2, size=6)

提取的點對關系如下所示
在這里插入圖片描述
提取出的重疊區域
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/40964.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/40964.shtml
英文地址,請注明出處:http://en.pswp.cn/web/40964.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

面試專區|【52道微服務架構高頻題整理(附答案背誦版)】

簡述什么是微服務&#xff1f; 微服務是一種軟件架構風格&#xff0c;它將應用程序拆分成一系列小型、獨立的服務&#xff0c;每個服務都運行在其自己的進程中&#xff0c;通過輕量級通信機制進行通信。每個服務都具有明確的業務能力&#xff0c;并且可以獨立開發、測試、部署…

Android在framework層添加自定義服務的流程

環境說明 ubuntu16.04android4.1java version “1.6.0_45”GNU Make 3.81gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12) 可能有人會問&#xff0c;現在都2024了怎么還在用android4版本&#xff0c;早都過時了。確實&#xff0c;現在最新的都是Android13、And…

墨烯的C語言技術棧-C語言基礎-007

七.字符串 由雙引號引起的一串字符稱為字符串字面值,或者簡稱字符串 字符串的結束標志是"\0" int main() { //#qWer$ //char 字符類型 //a; //char ch "w"; //字符串 //C語言中沒有字符串類型 "abcdefg"; char arr1[] "abc…

柯橋職場英語學習商務英語口語生活英語培訓生活口語學習

辣妹用英語怎么說&#xff1f; 辣妹在英語中通常被翻譯為“hot girl”或“spicy girl”&#xff0c;但更常見和直接的是“hot chick”或簡單地使用“hot”來形容。 舉個例子: Shes a real hot girl with her trendy outfit and confident attitude. 她真是個辣妹&#xff0…

Redis---10---SpringBoot集成Redis

SpringBoot集成Redis 總體概述jedis-lettuce-RedisTemplate三者的聯系 本地Java連接Redis常見問題&#xff0c;注意 bind配置請注釋掉? 保護模式設置為no? Linux系統的防火墻設置? redis服務器的IP地址和密碼是否正確? 忘記寫訪問redis的服務端口號和auth密碼集成Jedis …

Docker:Docker網絡

Docker Network 是 Docker 平臺中的一項功能&#xff0c;允許容器相互通信以及與外界通信。它提供了一種在 Docker 環境中創建和管理虛擬網絡的方法。Docker 網絡使容器能夠連接到一個或多個網絡&#xff0c;從而使它們能夠安全地共享信息和資源。 預備知識 推薦先看視頻先有…

最長公共子序列求長度和輸出子序列C代碼

求兩個字符串的公共子序列我們都知道需要使用用動態規劃思想 用res[i][j]表示截止到字符串A的第i個字符串和截止到字符串B的第j個字符的最長公共子序列。如兩個字符串helloworld和loop&#xff0c;res[5][3]表示子串hello和子串loo的最長公共子序列&#xff0c;為lo&#xff0…

2024機器人科研/研發領域最新研究方向崗位職責與要求

具身智能工程師 從事具身智能領域的技術研究或產品開發&#xff0c;制定具身智能技術標準&#xff0c;利用大模型技術來提高機器人的智能化水平&#xff0c;研究端云協同的機器人系統框架&#xff0c;并賦能人形/復合等各類形態的機器人。具體內容包括不限于&#xff1a; 1、負…

maven項目使用netty,前端是vue2,實現通訊

引入的java包 <!-- 以下是即時通訊--><!-- Netty core modules --><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.76.Final</version> <!-- 使用最新的穩定版本…

C++初學者指南-4.診斷---地址檢測器

C初學者指南-4.診斷—地址檢測器 幻燈片 地址檢測器&#xff08;ASan&#xff09; 適用編譯器g,clang檢測內存錯誤 內存泄露訪問已經釋放的內存訪問不正確的堆棧區域 用額外的指令檢測代碼 運行時間增加約70%內存使用量大約增加了3倍 示例&#xff1a;檢測空指針 使用地址…

中英雙語介紹百老匯著名歌劇:《貓》(Cats)和《劇院魅影》(The Phantom of the Opera)

中文版 百老匯著名歌劇 百老匯&#xff08;Broadway&#xff09;是世界著名的劇院區&#xff0c;位于美國紐約市曼哈頓。這里匯集了許多著名的音樂劇和歌劇&#xff0c;吸引了全球各地的觀眾。以下是兩部百老匯的經典音樂劇&#xff1a;《貓》和《劇院魅影》的詳細介紹。 1.…

CP AUTOSAR標準之RAMTest(AUTOSAR_CP_SWS_RAMTest)(更新中……)

1 簡介和功能概述 AUTOSAR基礎軟件模塊“RAM測試”的功能、API和配置。 ??RAM測試是對RAM單元的物理健康狀況的測試。它不是為了測試RAM的內容。用于寄存器的RAM也經過測試。 ??在本文檔中,RAM單元被理解為內存單位,可由處理器單獨尋址。因此,對于16位處理器,單元大小(…

拉普拉斯逆變換

https://www.bilibili.com/video/BV17i4y1475Y?p21&vd_source2e6b4ba548ec9462b2f9633ff700e9b9 CV 17 陳永平教授關于拉普拉斯逆變換的式子的推導 最關鍵的兩步 想到取一個合適的contour L R L_R LR?部分是實部 γ \gamma γ要大于所有極點的實部,這樣就可以搞一個大…

SCI二區TOP|麋鹿群優化算法: 一種新穎的受自然啟發的元啟發式算法

目錄 1.背景2.算法原理2.1算法思想2.2算法過程 3.結果展示4.參考文獻5.代碼獲取 1.背景 2024年&#xff0c;SO Oladejo受到麋鹿群的繁殖過程啟發&#xff0c;提出了麋鹿群優化算法&#xff08;Elk herd optimizer, EHO&#xff09;。 2.算法原理 2.1算法思想 EHO靈感來自麋鹿…

設計外包管理辦法和步驟之HMI

設計外包流程和步驟之人機界面HMI, Human-Machine Interface 1. 源由2. 流程&步驟2.1 明確需求2.2 尋找外包公司2.3 簽訂合同2.4 項目啟動2.5 設計過程2.6 迭代開發2.7 驗收和交付2.8 維護和支持 3. 工具和平臺推薦4. 總結5. 補充 - 需求、交付、驗收5.1 需求5.2 交付5.3 驗…

C語言編程與進階

1.0 C語言關鍵字 1-1C語言關鍵字-CSDN博客文章瀏覽閱讀831次&#xff0c;點贊13次&#xff0c;收藏24次。define使用define定義常量return 0;使用define定義宏// define 定義宏&#xff0c;名字是ADD(x,y),x y 是宏的參數int a 10;int b 20;return 0;宏定義的本質是替換&am…

pandas讀取CSV格式文件生成數據發生器iteration

背景 數據集標簽為csv文件格式&#xff0c;有三個字段column_hander [‘id’, ‘boneage’, ‘male’]&#xff0c;需要自己定義數據集。文件較大&#xff0c;做一個數據發生器迭代更新數據集。 實現模板 在Pandas中&#xff0c;可以使用pandas.read_csv函數讀取CSV文件&…

ShardingSphere實戰

ShardingSphere實戰 文章目錄 ShardingSphere實戰分庫分表實戰建表建表sql利用存儲過程建表Sharding-jdbc分庫分表配置 基于業務的Sharding-key考慮訂單id用戶id分片策略訂單id的設計與實現**設計思想**&#xff1a;設計思路&#xff1a; 具體分片策略實現測試數據插入商戶商品…

推薦好玩的工具之OhMyPosh使用

解除禁止腳本 Set-ExecutionPolicy RemoteSigned 下載Oh My Posh winget install oh-my-posh 或者 Install-Module oh-my-posh -Scope AllUsers 下載Git提示 Install-Module posh-git -Scope CurrentUser 或者 Install-Module posh-git -Scope AllUser 下載命令提示 Install-Mo…

SwinUnet詳解

文章目錄 摘要一. 編碼端模塊1. PatchEmbed2. SwinTransformerBlock2.1. Window_partition2.2. WindowAttention2.3. Window_reverse2.4. MLP 3. PatchMerging 二. 解碼端模塊三. 完整流程圖 摘要 swinunet基本結構&#xff1a; swinunet采用編碼器-解碼器結構&#xff1a; 編…