目标跟踪之DeepSort算法(4)
目标跟踪之DeepSort
- 1 安装
- 1.1 代码下载与安装
- 1. 2 DeepSort检测流程
- 1.3 模型初始化流程
- 2. 模型推理
- 2.1 模型推理代码解析
- 2.2 对预测结果跟踪代码解析
- 2.3 轨迹预测
- 2.4 轨迹跟踪
- 2.5 轨迹与特征匹配
- 2.6 计算轨迹与检测的特征余弦距离
- 2.7 用轨迹与检测的马氏距离跟新cost_matrix矩阵
1 安装
参考:https://github.com/beeduchai/YOLOv8-DeepSORT-Object-Tracking
1.1 代码下载与安装
1 创建一个全新的虚拟环境
conda create -n yolov8_deepsort python=3.9
2 激活虚拟环境
conda activate yolov8_deepsort
3 在当前地址创建一个文件夹存放将要下载的YOLOv8-DeepSORT-Object-Tracking
mkdir my_yolov8_deepsort
4 跳转到yolov8_deepsort 文件夹
cd my_yolov8_deepsort
5 下载代码
git clone https://github.com/MuhammadMoinFaisal/YOLOv8-DeepSORT-Object-Tracking.git
6 安装依赖库
pip install -e .
7 在https://drive.google.com/drive/folders/1kna8eWGrSfzaR6DtNJ8_GchGgPMv3VC8下载文件,将文件夹解压放在ultralytics/yolo/v8/detect目录下
8 在ultralytics/yolo/v8/detect放一个视频,执行以下命令.首次执行以下代码,会自动取下载yolov8l.pt模型
python predict.py model=yolov8l.pt source="traffic.mp4" show=True
注释:如果出现错误,可能是库的版本不对,根据报错提示更改版本。
1. 2 DeepSort检测流程
DeepSort检测流程:
- 模型初始化
- 模型推理
# ultralytics/yolo/v8/detect/predict.py
def predict(cfg): # cfg:ultralytics/yolo/configs/default.yaml # 1.模型初始化init_tracker() cfg.model = cfg.model or "yolov8n.pt"cfg.imgsz = check_imgsz(cfg.imgsz, min_dim=2) # check image sizecfg.source = cfg.source if cfg.source is not None else ROOT / "assets"# 2. 模型推理predictor = DetectionPredictor(cfg)predictor()
1.3 模型初始化流程
- 实例化对象获取"deep_sort_pytorch/configs/deep_sort.yaml"的参数。
- 初始化跟踪器
2.1 实例化特征提取器
2.2 实例化匹配代价矩阵
2.3 实例化跟踪器
# ultralytics/yolo/v8/detect/predict.py
def init_tracker():global deepsort# 1 实例化对象获取"deep_sort_pytorch/configs/deep_sort.yaml"的参数cfg_deep = get_config() cfg_deep.merge_from_file("deep_sort_pytorch/configs/deep_sort.yaml")# 2 初始化跟踪器deepsort= DeepSort(cfg_deep.DEEPSORT.REID_CKPT,max_dist=cfg_deep.DEEPSORT.MAX_DIST, min_confidence=cfg_deep.DEEPSORT.MIN_CONFIDENCE,nms_max_overlap=cfg_deep.DEEPSORT.NMS_MAX_OVERLAP, max_iou_distance=cfg_deep.DEEPSORT.MAX_IOU_DISTANCE,max_age=cfg_deep.DEEPSORT.MAX_AGE, n_init=cfg_deep.DEEPSORT.N_INIT, nn_budget=cfg_deep.DEEPSORT.NN_BUDGET,use_cuda=True)# ultralytics/yolo/v8/detect/deep_sort_pytorch/deep_sort/deep_sort.py
class DeepSort(object):def __init__(self, model_path, max_dist=0.2, min_confidence=0.3, nms_max_overlap=1.0, max_iou_distance=0.7, max_age=70, n_init=3, nn_budget=100, use_cuda=True):self.min_confidence = min_confidence # 检测物体的最小置信度self.nms_max_overlap = nms_max_overlap # NMS时iou的最大值# 2.1 实例化特征提取器self.extractor = Extractor(model_path, use_cuda=use_cuda) # 提取检测到的物体的特征,用于计算轨迹与检测框的余弦距离max_cosine_distance = max_dist # 计算距离的最大值2.2 实例化匹配代价矩阵metric = NearestNeighborDistanceMetric("cosine", max_cosine_distance, nn_budget) # metric计算匹配代价矩阵。在级联匹配中用欧式距离计算特级特征和检测特征的距离2.3 实例化跟踪器self.tracker = Tracker(metric, max_iou_distance=max_iou_distance, max_age=max_age, n_init=n_init)
2. 模型推理
模型推理流程:
- 准备模型和数据,对数据进行预处理
1.1 数据进行预处理 - 数据带入模型得到预测结果
- 处理预测结果
3.1 处理预测结果 - 对预测结果跟踪
2.1 模型推理代码解析
# ultralytics/yolo/engine/predictor.py@smart_inference_mode()def __call__(self, source=None, model=None):# 1.准备模型和数据,对数据进行预处理self.run_callbacks("on_predict_start")model = self.model if self.done_setup else self.setup(source, model)model.eval()self.seen, self.windows, self.dt = 0, [], (ops.Profile(), ops.Profile(), ops.Profile())self.all_outputs = []for batch in self.dataset:self.run_callbacks("on_predict_batch_start")path, im, im0s, vid_cap, s = batchvisualize = increment_path(self.save_dir / Path(path).stem, mkdir=True) if self.args.visualize else Falsewith self.dt[0]:im = self.preprocess(im)if len(im.shape) == 3:im = im[None] # expand for batch dim# 2. 数据带入模型得到预测结果# Inferencewith self.dt[1]:preds = model(im, augment=self.args.augment, visualize=visualize)# 3. 处理预测结果# postprocesswith self.dt[2]:preds = self.postprocess(preds, im, im0s)for i in range(len(im)):if self.webcam:path, im0s = path[i], im0s[i]p = Path(path)# 4. 对预测结果跟踪s += self.write_results(i, preds, (p, im, im0s))if self.args.show:self.show(p)if self.args.save:self.save_preds(vid_cap, i, str(self.save_dir / p.name))# Print time (inference-only)LOGGER.info(f"{s}{'' if len(preds) else '(no detections), '}{self.dt[1].dt * 1E3:.1f}ms")self.run_callbacks("on_predict_batch_end")# Print resultst = tuple(x.t / self.seen * 1E3 for x in self.dt) # speeds per imageLOGGER.info(f'Speed: %.1fms pre-process, %.1fms inference, %.1fms postprocess per image at shape {(1, 3, *self.imgsz)}'% t)if self.args.save_txt or self.args.save:s = f"\n{len(list(self.save_dir.glob('labels/*.txt')))} labels saved to {self.save_dir / 'labels'}" if self.args.save_txt else ''LOGGER.info(f"Results saved to {colorstr('bold', self.save_dir)}{s}")self.run_callbacks("on_predict_end")return self.all_outputs# 1.1 数据进行预处理 ultralytics/yolo/v8/detect/predict.pydef preprocess(self, img):img = torch.from_numpy(img).to(self.model.device) # 图片数据转换成tensor格式img = img.half() if self.model.fp16 else img.float() # uint8 to fp16/32 选择半精度还是双精度img /= 255 # 0 - 255 to 0.0 - 1.0 # 图片数据缩放到0~1之间return img# 3.1 处理预测结果 ultralytics/yolo/v8/detect/predict.pydef postprocess(self, preds, img, orig_img):# 1 非极大值抑制preds = ops.non_max_suppression(preds,self.args.conf,self.args.iou,agnostic=self.args.agnostic_nms,max_det=self.args.max_det) for i, pred in enumerate(preds):shape = orig_img[i].shape if self.webcam else orig_img.shape# 2 把检测到的框映射到原图pred[:, :4] = ops.scale_boxes(img.shape[2:], pred[:, :4], shape).round()return preds
2.2 对预测结果跟踪代码解析
把检测框的中心点宽高、置信度、类别、原图输入 deepsort.update()中进行跟踪,跟踪代码流程如下:
- 提取特征。
- 轨迹预测。
- 轨迹跟踪。
# ultralytics/yolo/v8/detect/predict.py-->def write_results(self, idx, preds, batch)-->outputs = deepsort.update(xywhs, confss, oids, im0)--> self.tracker.predict() self.tracker.update(detections)def update(self, bbox_xywh, confidences, oids, ori_img):self.height, self.width = ori_img.shape[:2]# generate detections # 1. 提取特征features = self._get_features(bbox_xywh, ori_img) # 提取检测框对应物体的特征bbox_tlwh = self._xywh_to_tlwh(bbox_xywh) # 把框由中心点宽高的格式转换为左上角坐标和宽高的格式detections = [Detection(bbox_tlwh[i], conf, features[i],oid) for i, (conf,oid) in enumerate(zip(confidences,oids)) if conf > self.min_confidence] # 删除资信度小于阈值的检测框,并把检测框的特征添加到detections中# run on non-maximum supressionboxes = np.array([d.tlwh for d in detections])scores = np.array([d.confidence for d in detections])# update tracker# 2. 轨迹预测self.tracker.predict()# 3. 轨迹跟踪self.tracker.update(detections)# output bbox identitiesoutputs = []for track in self.tracker.tracks:if not track.is_confirmed() or track.time_since_update > 1:continue box = track.to_tlwh()x1, y1, x2, y2 = self._tlwh_to_xyxy(box)track_id = track.track_idtrack_oid = track.oidoutputs.append(np.array([x1, y1, x2, y2, track_id, track_oid], dtype=np.int))if len(outputs) > 0:outputs = np.stack(outputs, axis=0)return outputs
2.3 轨迹预测
ultralytics/yolo/v8/detect/deep_sort_pytorch/deep_sort/sort/kalman_filter.py
self.tracker.predict()–>track.predict(self.kf)–>def predict(self, mean, covariance)
轨迹预测预测流程:
- 状态转移矩阵。
- 根据状态转移矩阵获取下一状态和其协方差。
def predict(self, mean, covariance):"""Run Kalman filter prediction step.Parameters----------mean : ndarrayThe 8 dimensional mean vector of the object state at the previoustime step.covariance : ndarrayThe 8x8 dimensional covariance matrix of the object state at theprevious time step.Returns-------(ndarray, ndarray)Returns the mean vector and covariance matrix of the predictedstate. Unobserved velocities are initialized to 0 mean."""std_pos = [self._std_weight_position * mean[3],self._std_weight_position * mean[3],1e-2,self._std_weight_position * mean[3]]std_vel = [self._std_weight_velocity * mean[3],self._std_weight_velocity * mean[3],1e-5,self._std_weight_velocity * mean[3]]# 1. 状态转移矩阵motion_cov = np.diag(np.square(np.r_[std_pos, std_vel]))# 2. 根据状态转移矩阵获取下一状态和其协方差mean = np.dot(self._motion_mat, mean)covariance = np.linalg.multi_dot((self._motion_mat, covariance, self._motion_mat.T)) + motion_covreturn mean, covariance
2.4 轨迹跟踪
ultralytics/yolo/v8/detect/deep_sort_pytorch/deep_sort/sort/tracker.py
self.tracker.update(detections)
轨迹跟踪步骤:
- 轨迹与特征匹配
- 更新匹配轨迹、未匹配轨迹和未匹配检测
- 更新轨迹的特征
def update(self, detections):"""Perform measurement update and track management.Parameters---------- bbox_tlwh[i], conf, features[i],oiddetections : List[deep_sort.detection.Detection]A list of detections at the current time step."""# Run matching cascade. 1. 轨迹与特征 级联匹配和IOU匹配matches, unmatched_tracks, unmatched_detections = \self._match(detections)# Update track set. 2. 更新匹配轨迹、未匹配轨迹和未匹配检测for track_idx, detection_idx in matches:self.tracks[track_idx].update(self.kf, detections[detection_idx]) # 对匹配轨迹更新得到当前最优轨迹for track_idx in unmatched_tracks:self.tracks[track_idx].mark_missed() # 对未匹配轨迹进行标识for detection_idx in unmatched_detections:self._initiate_track(detections[detection_idx]) # 对新检测框初始化轨迹self.tracks = [t for t in self.tracks if not t.is_deleted()] # 剔除掉删除的轨迹# Update distance metric. 3. 更新轨迹的历史特征active_targets = [t.track_id for t in self.tracks if t.is_confirmed()] # 存放确认状态轨迹的idfeatures, targets = [], [] # 分别存放当前所有轨迹的特征和idfor track in self.tracks:if not track.is_confirmed():continuefeatures += track.featurestargets += [track.track_id for _ in track.features]track.features = []self.metric.partial_fit( #np.asarray(features), np.asarray(targets), active_targets)
2.5 轨迹与特征匹配
轨迹与特征匹配步骤:
- 把轨迹分为确认状态和非确认状态。
- 级联匹配。通过级联匹配得到确认匹配轨迹和检测的id
matches_a,未匹配轨迹unmatched_tracks_a, 未匹配检测unmatched_detections - IOU匹配。把级联匹配步骤中只有一次未匹配的轨迹并如非确认轨迹用于IOU匹配;保留级联匹配步骤中未匹配的轨迹中连续2帧或2帧以上没有匹配的轨迹。
- 更新级联匹配和IOU匹配的结果。
def _match(self, detections):def gated_metric(tracks, dets, track_indices, detection_indices):features = np.array([dets[i].feature for i in detection_indices]) # 检测框的特征targets = np.array([tracks[i].track_id for i in track_indices]) # 轨迹的idcost_matrix = self.metric.distance(features, targets) # 计算轨迹与检测的特征余弦距离cost_matrix = linear_assignment.gate_cost_matrix( # 用轨迹与检测的马氏距离跟新cost_matrix矩阵self.kf, cost_matrix, tracks, dets, track_indices,detection_indices)return cost_matrix# Split track set into confirmed and unconfirmed tracks.# 1 把轨迹分为确认状态和非确认状态confirmed_tracks = [i for i, t in enumerate(self.tracks) if t.is_confirmed()]unconfirmed_tracks = [i for i, t in enumerate(self.tracks) if not t.is_confirmed()]# Associate confirmed tracks using appearance features. # 2 级联匹配matches_a, unmatched_tracks_a, unmatched_detections = \linear_assignment.matching_cascade(gated_metric, self.metric.matching_threshold, self.max_age,self.tracks, detections, confirmed_tracks)# Associate remaining tracks together with unconfirmed tracks using IOU.# 3 IOU匹配iou_track_candidates = unconfirmed_tracks + [k for k in unmatched_tracks_a ifself.tracks[k].time_since_update == 1] # 如果级联未匹配轨迹上一帧匹配成功,这一帧匹配失败,则把其添加到不确认轨迹中unmatched_tracks_a = [k for k in unmatched_tracks_a ifself.tracks[k].time_since_update != 1] # 跟新unmatched_tracks_a,只保留大于等于连续两帧没有被匹配上的matches_b, unmatched_tracks_b, unmatched_detections = \linear_assignment.min_cost_matching(iou_matching.iou_cost, self.max_iou_distance, self.tracks,detections, iou_track_candidates, unmatched_detections) # IOU匹配# 4 更新级联匹配和IOU匹配的结果matches = matches_a + matches_bunmatched_tracks = list(set(unmatched_tracks_a + unmatched_tracks_b))return matches, unmatched_tracks, unmatched_detectionsdef _initiate_track(self, detection):mean, covariance = self.kf.initiate(detection.to_xyah()) # 根据新检测到的框初始化轨迹的数值和协方差self.tracks.append(Track(mean, covariance, self._next_id, self.n_init, self.max_age,detection.oid,detection.feature)) # 添加新的轨迹self._next_id += 1# 2 级联匹配
级联匹配步骤:
2.1 获取(1 + level)次没有被匹配上的轨迹
2.2 计算轨迹特征和检测特征的代价矩阵2.2.1 计算轨迹与检测的特征余弦距离2.2.2 用轨迹与检测的马氏距离跟新cost_matrix矩阵def matching_cascade(distance_metric, max_distance, cascade_depth, tracks, detections,track_indices=None, detection_indices=None):"""Run matching cascade.Parameters----------distance_metric : Callable[List[Track], List[Detection], List[int], List[int]) -> ndarrayThe distance metric is given a list of tracks and detections as well asa list of N track indices and M detection indices. The metric shouldreturn the NxM dimensional cost matrix, where element (i, j) is theassociation cost between the i-th track in the given track indices andthe j-th detection in the given detection indices.max_distance : floatGating threshold. Associations with cost larger than this value aredisregarded.cascade_depth: intThe cascade depth, should be se to the maximum track age.tracks : List[track.Track]A list of predicted tracks at the current time step.detections : List[detection.Detection]A list of detections at the current time step.track_indices : Optional[List[int]]List of track indices that maps rows in `cost_matrix` to tracks in`tracks` (see description above). Defaults to all tracks.detection_indices : Optional[List[int]]List of detection indices that maps columns in `cost_matrix` todetections in `detections` (see description above). Defaults to alldetections.Returns-------(List[(int, int)], List[int], List[int])Returns a tuple with the following three entries:* A list of matched track and detection indices.* A list of unmatched track indices.* A list of unmatched detection indices."""if track_indices is None:track_indices = list(range(len(tracks)))if detection_indices is None:detection_indices = list(range(len(detections)))unmatched_detections = detection_indices # 初始所有的检测都没有匹配matches = []for level in range(cascade_depth):if len(unmatched_detections) == 0: # No detections leftbreak# 1 获取(1 + level)次没有被匹配上的轨迹track_indices_l = [k for k in track_indicesif tracks[k].time_since_update == 1 + level ]if len(track_indices_l) == 0: # Nothing to match at this levelcontinue# 2 计算轨迹特征和检测特征的马氏距离matches_l, _, unmatched_detections = \min_cost_matching(distance_metric, max_distance, tracks, detections, # max_distance阈值track_indices_l, unmatched_detections)matches += matches_lunmatched_tracks = list(set(track_indices) - set(k for k, _ in matches))return matches, unmatched_tracks, unmatched_detections
2.6 计算轨迹与检测的特征余弦距离
对检测特征和历史的轨迹特征先归一化,再1减去特征的矩阵相乘得到余弦距离
def _cosine_distance(a, b, data_is_normalized=False):"""Compute pair-wise cosine distance between points in `a` and `b`.Parameters----------a : array_likeAn NxM matrix of N samples of dimensionality M.b : array_likeAn LxM matrix of L samples of dimensionality M.data_is_normalized : Optional[bool]If True, assumes rows in a and b are unit length vectors.Otherwise, a and b are explicitly normalized to lenght 1.Returns-------ndarrayReturns a matrix of size len(a), len(b) such that element (i, j)contains the squared distance between `a[i]` and `b[j]`."""if not data_is_normalized:a = np.asarray(a) / np.linalg.norm(a, axis=1, keepdims=True) # a是轨迹特征归一化b = np.asarray(b) / np.linalg.norm(b, axis=1, keepdims=True) # b是检测特征归一化return 1. - np.dot(a, b.T)
2.7 用轨迹与检测的马氏距离跟新cost_matrix矩阵
根据公式计算马氏距离
def gate_cost_matrix(kf, cost_matrix, tracks, detections, track_indices, detection_indices,gated_cost=INFTY_COST, only_position=False):"""Invalidate infeasible entries in cost matrix based on the statedistributions obtained by Kalman filtering.Parameters----------kf : The Kalman filter.cost_matrix : ndarrayThe NxM dimensional cost matrix, where N is the number of track indicesand M is the number of detection indices, such that entry (i, j) is theassociation cost between `tracks[track_indices[i]]` and`detections[detection_indices[j]]`.tracks : List[track.Track]A list of predicted tracks at the current time step.detections : List[detection.Detection]A list of detections at the current time step.track_indices : List[int]List of track indices that maps rows in `cost_matrix` to tracks in`tracks` (see description above).detection_indices : List[int]List of detection indices that maps columns in `cost_matrix` todetections in `detections` (see description above).gated_cost : Optional[float]Entries in the cost matrix corresponding to infeasible associations areset this value. Defaults to a very large value.only_position : Optional[bool]If True, only the x, y position of the state distribution is consideredduring gating. Defaults to False.Returns-------ndarrayReturns the modified cost matrix."""gating_dim = 2 if only_position else 4gating_threshold = kalman_filter.chi2inv95[gating_dim]measurements = np.asarray([detections[i].to_xyah() for i in detection_indices])for row, track_idx in enumerate(track_indices):track = tracks[track_idx] # gating_distance马氏距离gating_distance = kf.gating_distance( # track.mean, track.covariance是轨迹的均值和协方差。measurements是检测框track.mean, track.covariance, measurements, only_position)cost_matrix[row, gating_distance > gating_threshold] = gated_cost # 如果马氏距离大于阈值,则赋值为极大值。return cost_matrix# 马氏距离def gating_distance(self, mean, covariance, measurements,only_position=False):"""Compute gating distance between state distribution and measurements.A suitable distance threshold can be obtained from `chi2inv95`. If`only_position` is False, the chi-square distribution has 4 degrees offreedom, otherwise 2.Parameters----------mean : ndarrayMean vector over the state distribution (8 dimensional).covariance : ndarrayCovariance of the state distribution (8x8 dimensional).measurements : ndarrayAn Nx4 dimensional matrix of N measurements, each informat (x, y, a, h) where (x, y) is the bounding box centerposition, a the aspect ratio, and h the height.only_position : Optional[bool]If True, distance computation is done with respect to the boundingbox center position only.Returns-------ndarrayReturns an array of length N, where the i-th element contains thesquared Mahalanobis distance between (mean, covariance) and`measurements[i]`."""mean, covariance = self.project(mean, covariance) # 轨迹特征if only_position: # 计算马氏距离用几个值mean, covariance = mean[:2], covariance[:2, :2]measurements = measurements[:, :2]cholesky_factor = np.linalg.cholesky(covariance) # 对轨迹的协方差分解成下三角矩阵和,前提covariance正定d = measurements - mean #(det-track).T *track's covariance.INV *(det-track)z = scipy.linalg.solve_triangular( # 求线性方程组的解 mash = d.T *covariance^{-1} *d = d.T *(L.T*L) *d = (Ld).T*(Ld)cholesky_factor, d.T, lower=True, check_finite=False, # L.T*? = d.T--> ? = ((L.T)^{-1} d.T=(dL^{-1}).Toverwrite_b=True)squared_maha = np.sum(z * z, axis=0)return squared_maha
相关文章:
目标跟踪之DeepSort算法(4)
目标跟踪之DeepSort 1 安装1.1 代码下载与安装1. 2 DeepSort检测流程1.3 模型初始化流程 2. 模型推理2.1 模型推理代码解析2.2 对预测结果跟踪代码解析2.3 轨迹预测2.4 轨迹跟踪2.5 轨迹与特征匹配2.6 计算轨迹与检测的特征余弦距离2.7 用轨迹与检测的马氏距离跟新cost_matrix矩…...
速通大厂测开
最近26届暑期实习招聘和25届春招已经开始,测开学习圈也有同学拿到offer了 今天分享一位25届秋招圈友快速拿到大厂测开offer的经历,希望对大家有所帮助 我是某211本科生,在去年暑假准备考研的间隙意外收获了某大厂测开实习offer,…...
LightRAG简要概述
文章目录 索引流程问答流程naivelocalglobalhybridmix 中文prompt 官方仓库:LightRAG 没有废话,直接进入主题。 索引流程 1、提取实体与关系 2、LLM判断是否有漏掉的实体与关系,如有则接着提取 3、合并实体,根据多个实体描述&a…...
【Mac】安装 Parallels Desktop、Windows、Rocky Linux
一、安装PD 理论上,PD只支持试用15天!当然,你懂的。 第一步,在 Parallels Desktop for Mac 官网 下载 Install Parallels Desktop.dmg第二步,双击 Install Parallels Desktop.dmg 第三步,双击安装Paralle…...
Unity利用噪声生成动态地形
引言 在游戏开发中,地形是构建游戏世界的基础元素之一。传统的地形创建方法通常依赖于手动建模或预设资源,这种方式虽然精确但缺乏灵活性,且工作量巨大。而使用噪声算法生成地形则提供了一种程序化、动态且高效的解决方案。本文将详细介绍如…...
【Linux】Ext系列文件系统(上)
目录 一、 理解硬件 1-1 磁盘 1-2 磁盘物理结构 1-3 磁盘的存储结构 1-4 如何定位一个扇区 1-4 磁盘的逻辑结构 1-4-1 理解过程 1-4-2 真实过程 1-5 CHS && LBA地址 二、文件系统 2-1 "块"概念 2-2 "分区"概念 2-3 "inode"…...
解决diffusers加载stablediffusion模型,输入prompt总是报错token数超出clip最大长度限制
1. StableDiffusion1.5 在加载huggingface中的扩散模型时,输入prompt总是会被报错超过clip的最大长度限制。 解决方案:使用compel库 from diffusers import AutoPipelineForText2Image import torch import pdb from compel import Compeldevice torc…...
metersphere接口测试(1)使用MeterSphere进行接口测试
文章目录 前言接口文档单接口测试环境配置梳理接口测试场景测试接口 接口自动化怎么写复用性高的自动化测试用例 总结 前言 大汉堡工作第203天,本篇记录我第一次接触接口测试任务,最近有些懈怠啊~ 接口文档 首先就是接口地址,接口测试时用…...
Android第三次面试总结(网络篇)
在计算机网络领域,网络模型是理解通信原理的基础框架。本文将详细解析 OSI 参考模型和 TCP/IP 模型的分层结构、核心功能及实际应用,并通过对比帮助读者建立完整的知识体系。 一、OSI 参考模型:七层架构的理论基石 OSI(开放系统…...
AirtestIDE用法
包括airtest和poco 1. airtest 安装python3.7.9 64 python3 -m pip install -U airtest 或者: git clone https://github.com/AirtestProject/Airtest.git pip install -e airtest 无界面的airtest用法: 打开手机中的 开发者选项 , 以及 允许USB调…...
【面试手撕】非常规算法,多线程常见手撕题目
【面试手撕】非常规算法,多线程常见手撕题目 生产者消费者ReentrantLock实现的生产苹果/消费苹果synchronized实现的生产消费LinkedBlockingQueue阻塞队列方法实现多条件资源分配分布式任务调度模拟 交替打印两个线程交替打印1-100之间的数ReentrantLock 实现synchr…...
MySQL复合查询
目录 多表查询 自连接 子查询 单行子查询 多行子查询 in关键字 all关键字 any关键字 多列子查询 from中使用子查询 合并查询 union 操作符 union all 操作符 内外连接 内连接 外连接 左外连接 右外连接 前几期我们已经学习了MySQL的基本查询&…...
登录Xshell主机及Linux基本指令
✅博客主页:爆打维c-CSDN博客 🐾 🔹分享c、c知识及代码 🐾 🔹Gitee代码仓库 五彩斑斓黑1 (colorful-black-1) - Gitee.com 一、操作系统简介 Linux其实跟我们熟知的Window一样,它们都是操作系统。 &#x…...
[LevelDB]关于LevelDB存储架构到底怎么设计的?
本文内容组织形式 LevelDB 存储架构重要特点总体概括LevelDB中内存模型MemTableMemTable的数据结构背景:SkipListSkiplist的数据结构 Skiplist的数据访问细节 SkipList的核心方法Node细节源代码 MemTable的数据加速方式Iterator 的核心方法 MemTable 的读取&写入…...
深入解析 React Diff 算法:原理、优化与实践
深入解析 React Diff 算法:原理、优化与实践 1. 引言 React 作为前端领域的标杆框架,采用 虚拟 DOM(Virtual DOM) 来提升 UI 更新性能。React 的 Diff 算法(Reconciliation) 是虚拟 DOM 运行机制的核心&a…...
【从零开始】Air780EPM的LuatOS二次开发——OneWire协议调试注意事项!
当涉及到与传感器、执行器等外部设备交互时,OneWire协议的高效调试成为决定项目成败的关键环节。OneWire协议(单总线协议)以其仅需一根数据线即可实现设备通信的极简特性,被广泛应用于温度传感器、身份识别模块等场景。 一、LuatO…...
响应(Response)
在 Flask 中,视图函数可以返回多种类型的响应,例如字符串、HTML、JSON、文件等。Flask 提供了 make_response 函数,用于生成和自定义 HTTP 响应。 2.1 默认响应 默认情况下,视图函数返回的字符串会被 Flask 包装成一个 HTTP 响应…...
C++学习之云盘项目fastDFS
1.资料介绍 1.1 一些概念 1. 什么是服务器 硬件 : 一台配置高的电脑 软件 : 电脑必须有一个能够解析 http 协议的软件 2. 常见的 Web 服务器 tomcat 服务器 apache 组织产品 , 开源的免费服务器 weblogic 服务器 bea 公司 , 收费的服务器 不交费 , 访问量受限…...
使用vue3+el-form实现动态新增名称,值,并对名称进行必填校验
使用vue3el-form实现动态新增名称,值,并对名称进行必填校验 效果图 代码 <template><el-form :model"form" :rules"rules" ref"dynamicForm"><!-- 动态添加的名称和值 --><el-row v-for"(ite…...
Spring Boot 集成高德地图电子围栏
摘要:本文手把手教你通过 Spring Boot 调用高德地图 API 实现电子围栏功能,涵盖云端围栏创建、设备位置监控与本地算法校验,附带完整代码和避坑经验! 一、电子围栏核心原理 1.1 什么是电子围栏? 虚拟地理边界&#x…...
3.JVM-内部结构
栈结构 动态链接 栈中的对象指向堆中的实际引用 符号引用: 比如一个类的名称 直接引用: 具体堆中数据信息 方法返回 栈中上一层的结果和下一层的指令 操作数栈 局部变量 该线程中需要的变量 PC计数器 程序计数器:存当前执行到那一步 操作数栈里面将计算完之后的结果推入局…...
Spring 框架中常用注解和使用方法
Spring 框架中常用注解的详细解释与应用场景,结合核心功能和实际开发需求进行分类说明: 1.组件定义注解 1.1 Component 作用:通用注解,将普通 Java 类标记为 Spring 管理的 Bean,由容器实例化和管理,相当…...
神策数据接入 DeepSeek,AI 赋能数据分析与智能运营
在 AI 技术迅猛发展的浪潮下,神策数据正在加速推进人工智能在数据分析和智能运营领域的深度应用。近日,神策数据宣布全面接入 DeepSeek,为企业客户带来更加智能化、高效的数据分析与智能运营服务。这一举措展现了神策数据在人工智能方向的探索…...
微软OneNote无法同步解决方案
目录 前言原因UWP特性 解决方案C***h注册表 参考链接 前言 假设有多台Windows电脑,最方便且免费的多设备笔记同步方案就是微软自家的OneNote,使用OneDrive自带的5G云存储。 但是在国内大陆的OneNote,经常会出现无法同步、同步失败࿱…...
一般机器学习有哪些算法?
传统的机器学习算法主要依赖统计学和优化方法,不依赖深层神经网络,通常具有较高的可解释性且适用于中小规模数据集。以下是经典的传统机器学习算法分类及代表性模型: 一、监督学习(Supervised Learning) 1. 回归&…...
RAGFlow部署与使用(开源本地知识库管理系统,包括kibana配置)
一、RAGFlow 简介 戳我访问RAGFlow RAGFlow 是一款基于深度文档理解构建的开源 RAG(Retrieval-Augmented Generation)引擎。它可以给我们搭建本地知识库,将用户的知识文档上传到RAGFlow后,通过文档切分、向量入库,在…...
STM32G070CBT6读写FLASH中的数据
向FLASH中写入数据函数 /*函数说明:向FLASH中写数据形参:addr-要写入数据的起始地址 data-准备写入数据 len-数据大小返回值:1-成功,0-失败 */ uint8_t FlashWriteData(uint64_t addr,uint8_t data[],size_t len) {uint32_t Fir…...
如何使用HACS一键集成米家与果家设备到HomeAssistant玩转智能家居
文章目录 前言1. 下载HACS源码2. 添加HACS商店3. 绑定米家设备 前言 各位科技潮人和智能家居发烧友们,是不是也梦想着把家里变成一个高科技的空间?有了群晖NAS这位得力助手,不仅存储空间大得吓人,还能通过Docker轻松安装各种应用…...
Flutter_学习记录_状态管理之GetX
1. 状态管理、Flutter Getx介绍 1.1 状态管理 通俗的讲:当我们想在多个页面(组件/Widget)之间共享状态(数据),或者一个页面(组件/Widget)中的多个子组件之间共享状态(数…...
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_09自定义单元格的固定表头表格
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕 目录 DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14_09自定义单元格…...
基于 Prometheus + Grafana 监控微服务和数据库
以下是基于 Prometheus Grafana 监控微服务和数据库的详细指南,包含架构设计、安装配置及验证步骤: 一、整体架构设计 二、监控微服务 1. 微服务指标暴露 Spring Boot 应用: xml <!-- 添加 Micrometer 依赖 --> <dependency>…...
文件解析漏洞
一,IIS解析漏洞 1,IIS6.X 目录解析 在iis的⽹站根⽬录新建⼀个名为q.asp的⽂件,在q.asp中新建⼀个txt⽂件 在外部浏览器中访问windows2003的iis⽹站中的1.txt 发现asp代码被执⾏ 2,IIS6.X 畸形文件解析 在iis的⽹站根⽬录新建⼀…...
C++学习笔记(二十一)——文件读写
一、文件读写 作用: 文件读写指的是将数据从程序存储到文件,或从文件读取数据,以实现数据的持久化存储。 C 提供了 fstream 头文件,用于文件操作,主要包括: ofstream(输出文件流)—…...
Ubuntu上部署Flask+MySQL项目
一、服务器安装python环境 1、安装gcc(Ubuntu默认已安装) 2、安装python源码 wget https://www.python.org/ftp/python/3.13.2/Python-3.13.2.tar.xz 3、安装Python依赖库 4、配置python豆瓣源 二、服务器安装虚拟环境 1、安装virtualenv pip3.10 ins…...
Unity WebGL项目访问时自动全屏
Unity WebGL项目访问时自动全屏 打开TemplateData/style.css文件 在文件最下方添加红色框内的两行代码 使用vscode或者其他编辑器打开index.html 将按钮注释掉,并且更改为默认全屏...
C#RTSP代理推流程序
将不支持rtsp的相机通过rtspserver实现推流 主要功能 1. rtsp交互 2. udp推流 3. Bitmap转H264,RTP打包 4. 支持多路播放...
Redis--渐进式遍历
目录 一、引言 二、介绍 三、命令 四、总结 一、引言 本篇文章将介绍Redis中的渐进式遍历 二、介绍 一般使用keys * 来获取所有的key,但这样的操作如果数据量很大的时候,会将服务器给卡死,所以通过渐进式遍历,就会避免这个问题…...
PyTorch深度学习框架60天进阶学习计划 - 第23天:Transformer架构解析
让我继续完成机器翻译示例的代码: PyTorch深度学习框架60天进阶学习计划:第23天 Transformer架构解析 学习目标 推导自注意力机制数学公式详解位置编码的傅里叶基函数设计对比编码器-解码器结构的信息流动差异 1. Transformer架构概述 Transformer架…...
《C#上位机开发从门外到门内》3-4:基于TCP/IP的远程监控系统设计与实现
文章目录 一、项目概述二、系统架构设计三、通信协议设计四、功能模块实现五、系统安全性与稳定性六、性能优化与测试七、实际应用案例八、结论 随着信息技术的飞速发展,远程监控系统在工业自动化、智能家居、环境监测等领域的应用日益广泛。基于TCP/IP协议的远程监…...
【MySQL】MySQL审计工具Audit Plugin安装使用
MySQL审计工具Audit Plugin安装使用 https://www.cnblogs.com/waynechou/p/mysql_audit.html MySQL 5.6 开启审计功能 https://blog.51cto.com/u_15127556/4344503 MySQL之添加日志审计功能 https://blog.csdn.net/weixin_43279032/article/details/105507170 MySQL开启日志记录…...
Flutter 按钮组件 ElevatedButton 详解
目录 1. 引言 2. ElevatedButton 的基本用法 3. 主要属性 4. 自定义按钮样式 4.1 修改背景颜色和文本颜色 4.2 修改按钮形状和边框 4.3 修改按钮大小 4.4 阴影控制 4.5 水波纹效果 5. 结论 相关推荐 1. 引言 在 Flutter 中,ElevatedButton 是一个常用的…...
AndroidStudio+Android8.0下的Launcher3 导入,编译,烧录,调试
文章目录 编译完成搜索输出文件Android.mk配置gradle编译环境报错一报错二报错三输出文件下载INSTALL_FAILED_TEST_ONLY查找系统签名查找签名工具开始签名查看签名签名问题重新生成秘钥解决方案生成成功挽救错误:重新刷机更换testkey秘钥keystore生成keystoreINSTALL_FAILED_S…...
【差分约束】P5590 赛车游戏|省选-
本文涉及知识点 【数学 线性代数】差分约束 P5590 赛车游戏 题目描述 R 君和小伙伴打算一起玩赛车。但他们被老司机 mocania 骗去了秋名山。 秋名山上有 n n n 个点和 m m m 条边,R 君和他的小伙伴要从点 1 1 1 出发开往点 n n n,每条边都有一个…...
咪咕MG101_晨星MSO9380芯片_安卓5.1.1_免拆卡刷固件包
咪咕MG101_晨星MSO9380芯片_安卓5.1.1_免拆卡刷固件包(内有教程) 刷机教程简单说明: 1、把下载好的刷机包,U盘里建立一个upgrade文件夹,固件放入此文件夹里,放入U盘中,注意升级包为压缩包不要对…...
【软件工程】06_软件设计
6.1 软件设计概述 1. 软件设计的目标 软件设计的最基本目标就是回答 “概括地描述系统如何实现用户所提出来的功能和性能等方面的需求?” 这个问题。 软件设计的目标是根据软件需求分析的结果,设想并设计软件,即根据目标系统的逻辑模型确定目标系统的物理模型。包括软件体系…...
在Flutter中使用Future读取一个大文件会导致线程阻塞吗
目录 一、Future 与文件读取的机制 1. Dart 的异步 I/O 原理 2. 代码示例 二、什么情况下会阻塞主线程? 1. I/O 操作本身不会阻塞 2. 数据处理可能阻塞 3. 示例对比 三、如何避免阻塞主线程? 1. 将耗时操作移到 Isolate 2. 使用 compute 函数(简化 Isolate 操作)…...
2025-03-17 Unity 网络基础1——网络基本概念
文章目录 1 网络1.1 局域网1.2 以太网1.3 城域网1.4 广域网1.5 互联网(因特网)1.6 万维网1.7 小结 2 IP 地址2.1 IP 地址2.2 端口号2.3 Mac 地址2.4 小结 3 客户端与服务端3.1 客户端3.2 服务端3.3 网络游戏中的客户端与服务端 1 网络 在没有网络之前…...
2025-03-17 学习记录--C/C++-PTA 习题4-8 高空坠球
合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。💪🏻 一、题目描述 ⭐️ 习题4-8 高空坠球 皮球从某给定高度自由落下,触地后反弹到原高度的一半,再落下&…...
Java网络编程socket
一、UDP 特点: ① 用户数据报协议(User Datagram Protocol) ② UDP是面向无连接通信协议 ③ 速度快,一次只能传输64KB数据,数据不安全,容易丢失 (1)单播 一对一 客户端…...
蓝桥杯备赛 Day0_移动零
🎈 个人主页👉:tbRNA-CSDN博客tbRNA-CSDN博客tbRNA-CSDN博客 💯 个人简介:在校大学生一枚💋. 😍 希望我的文章对大家有着不一样的帮助,欢迎大家关注我,感谢大家的多多支持…...