基于YOLOv8与DeepSORT实现多目标跟踪——算法与源码解析

news2024/11/24 11:51:36

一、概述

"目标跟踪 (Object Tracking)"是机器视觉领域中的一个重要研究领域。根据跟踪的目标数量,可以将其分为两大类:单目标跟踪 (Single Object Tracking,简称 SOT) 和多目标跟踪 (Multi Object Tracking,简称 MOT)。

多目标跟踪往往面临一些挑战,例如需要同时跟踪多个目标、目标可能频繁遮挡,这些因素使得目标跟丢成为一个常见问题。为了解决这些问题,可以借助跟踪器 DeepSORT 以及检测器 YOLO v8,从而构建一个高性能的实时多目标跟踪模型。

二、算法与项目流程

在深度学习领域中,目标跟踪是一项任务,旨在使用对象在空间和时间上的特征来预测它们在整个视频序列中的位置。从技术上讲,目标跟踪包括获取初始的目标检测集,为每个目标分配唯一的标识(ID),并在整个视频帧序列中跟踪它们,同时保持它们的标识不变。

1.目标检测与目标追踪

目标检测
在计算机视觉任务中,目标检测是在图像和视频(一系列的图像)中扫描和搜寻目标并给出目标所在图像的位置坐标(边界框):
在这里插入图片描述

在对视频进行检测时,也是把视频拆分成一帧帧来进行处理,这处理的过程中,检测所获取目标在帧与帧之间是无法进行关联的,假设,要对视频进行行人检测时,第一帧检测到了行人,第二帧也检测到同一个行人,但这两帧的这个行人目标是无法进行关联的,假设当前视频中有五个行人,目标检测只能检测到当前视频每一帧都有这个几个目标,并不能确定这几个目标中哪个是目标A,哪个是目标B,那个目标C等等。
视频示例:

行人检测

目标追踪
从上面的示例可以看出,当使用对象检测器时,只会得到一个包含对象位置信息的输出数组。这个输出数组可能包含多个坐标,每个坐标代表一个检测到的对象的位置。然而,这个输出数组通常不提供有关对象之间的关联信息,因此在查看输出数组时,你无法知道哪个坐标对应于哪个检测框。

与此不同,目标跟踪器在处理检测结果时为每个对象分配一个唯一的标识符(ID),并且会在整个帧序列中保持该ID不变,直到该对象的生命周期结束。这意味着,无论对象在视频中如何移动或遮挡,跟踪器都能够将相同的ID与该对象关联起来,以维护对象的一致性标识。这种ID分配使得跟踪器能够区分不同的对象,并跟踪它们的轨迹,而不仅仅是提供它们的位置信息。
视频示例:

运动目标追踪

目标检测和目标跟踪的区别
目标检测:

  • 目标检测任务要求同时完成对象的定位(即确定对象的边界框位置)和分类(即确定对象的类别)。这意味着目标检测算法必须不仅能够确定对象是否存在,还要知道它是什么。
  • 目标检测通常用于识别和定位图像或视频帧中的对象,通常需要明确的目标类别信息。

目标跟踪:

  • 目标跟踪任务更关注对象在帧与帧之间的连续性,通常更注重对象的运动特征,而不要求进行目标的分类。
  • 目标跟踪可以不涉及目标的类别,它的主要目标是维护对象的位置和轨迹,以实现在视频序列中的跟踪。

2.目标追踪的类型

目标跟踪器根据不同的分类标准可以分为多种类型:

  1. 单目标跟踪(Single Object Tracking,SOT):

    • 这类跟踪器专注于跟踪单个目标,即使在帧中存在多个其他对象。它们通常在第一帧中初始化目标的位置,然后在整个帧序列中跟踪它。一些传统的SOT方法包括CSRT、KCF等,但现在基于深度学习的跟踪器如GOTURN和SiamRPN表现更准确。
  2. 多目标跟踪(Multi Object Tracking,MOT):

    • 这些跟踪器具有能力同时跟踪多个目标,甚至可以跟踪不同类别的目标,并保持高速性能。它们通常在大规模数据集上进行训练,因此具有更高的准确性。一些强大的MOT算法包括DeepSORT、JDE和CenterTrack。
  3. 通过检测跟踪(Detection-Based Tracking):

    • 这种类型的跟踪算法首先使用目标检测器检测帧中的对象,然后跨帧执行数据关联以生成目标的轨迹,实现目标的跟踪。它们能够同时跟踪多个对象,并具备处理新对象引入的能力。即使目标检测失败,这些算法也有助于保持目标的跟踪。
  4. 无检测跟踪(Detection-Free Tracking):

    • 这种类型的跟踪算法需要手动初始化目标的位置,然后在后续帧中跟踪这些目标。这种方法通常使用传统的计算机视觉算法,而不依赖于目标检测。它们在一些特定应用中仍然有用。

不同类型的目标跟踪器适用于不同的应用场景,选择适当的跟踪器取决于任务要求、对象数量和性能要求。

3.目标跟踪的应用

  1. 交通监控:

    • 交通流量管理:目标跟踪可用于监控道路上的车辆,帮助交通管理部门更好地理解交通流量,进行交通优化和拥堵监测。
    • 违规行为检测:跟踪器可以检测和记录交通违规行为,如闯红灯、违规变道等,以提供证据用于执法。
  2. 体育运动/赛事:

    • 运动员跟踪:跟踪器可用于追踪运动员在比赛中的位置和移动,为教练和观众提供实时数据和分析。
    • 比赛统计:通过跟踪球员和球的位置,可以自动记录得分、犯规和其他比赛统计数据,减轻人工记录的工作量。
  3. 多摄像头监控:

    • 重新识别:核心思想是在多个摄像头之间重新识别相同的对象。如果一个对象在一个带有独特ID的摄像头中被跟踪,然后离开画面并在另一台摄像头中再次出现,跟踪器能够保持相同的ID,帮助重新识别对象。
    • 入侵检测:跟踪器可以用于监控区域,以检测不明对象的出现或不寻常的行为,从而帮助提高安全性。
  4. 智能监控和安全:

    • 安防监控:跟踪器可用于监控大型场所,如机场、商场和公共交通站,以监测潜在的威胁或异常行为。
    • 人脸跟踪:用于跟踪和记录人员的位置,特别是在人脸识别系统中,以进行出入记录或提供定位服务。
  5. 无人机和自动驾驶:

    • 无人机导航:目标跟踪可用于协助无人机导航和跟踪地面目标,例如搜索和救援、农业监测等。
    • 自动驾驶车辆:跟踪技术可以用于自动驾驶车辆中,以帮助车辆理解和预测其他交通参与者的行为。

4. 算法整合

在实际应用中,结合目标检测和目标跟踪可以实现更高效的处理方式。可以使用目标检测来定期锁定目标,然后使用目标跟踪来跟踪目标的位置,这样可以降低计算成本,同时可以定期进行目标分类,从而减轻系统的负担。这种方法可以有效提高处理速度,并在实际场景中得到广泛应用。

  1. 目标检测:

    • 使用目标检测算法在每一帧中检测出目标的位置和边界框。这一步可以提供当前帧中的目标位置信息。
  2. 特征提取:

    • 对每个检测到的目标,使用深度学习模型(如卷积神经网络,CNN)提取目标的特征表示。这些特征表示捕捉了目标的外观和特征,通常是高维向量。
  3. 目标匹配:

    • 将每个检测到的目标与先前帧中已跟踪的目标进行匹配,以确定目标的身份和轨迹。匹配过程通常考虑多个因素,包括目标的特征相似度、运动一致性、外观相似度等。
  4. 外观特征描述符:

    • 在目标匹配中,使用强大的外观特征描述符,如DeepSORT中所使用的,可以更准确地区分不同目标之间的相似度。这些描述符帮助算法区分不同目标,即使它们具有相似的外观特征。
  5. 处理复杂情况:

    • 目标跟踪还需要处理各种复杂情况,如目标的消失和重新出现、遮挡、变形等。算法需要具备鲁棒性,以支持长期目标跟踪,并能够应对这些挑战。

三、DeepSORT算法

DeepSORT是一种计算机视觉目标跟踪算法,旨在为每个对象分配唯一的ID并跟踪它们。它是SORT(Simple Online and Realtime Tracking,简单在线实时跟踪)算法的扩展和改进版本。SORT是一种轻量级目标跟踪算法,用于处理实时视频流中的目标跟踪问题。DeepSORT引入了深度学习技术,以加强SORT的性能,并特别关注在多个帧之间跟踪目标的一致性。

1. SORT目标追踪

SORT 是一种对象跟踪方法,其中使用卡尔曼滤波器和匈牙利算法等基本方法来跟踪对象,并声称比许多在线跟踪器更好。SORT 由以下 4 个关键组件组成:

  1. 检测:首先,在跟踪流程的第一步,目标检测器被用来检测当前帧中需要跟踪的目标对象。常用的目标检测器包括Faster R-CNN、YOLO等。

  2. 估计:在估计阶段,检测结果从当前帧传播到下一帧,使用恒速模型来估计下一帧中目标的位置。当检测结果与已知的目标相关联时,检测到的边界框信息用于更新目标的状态,包括速度分量,这是通过卡尔曼滤波器框架来实现的。

  3. 数据关联:在数据关联步骤中,目标的边界框信息与检测结果结合,从而形成一个成本矩阵,该矩阵计算每个检测与已知目标的所有预测边界框之间的交并比(IOU)距离。然后,使用匈牙利算法来优化分配,以确保正确地将检测结果与目标关联起来。这个技术有助于解决遮挡问题并保持目标的唯一身份。

  4. 管理目标ID的创建与删除:跟踪模块负责创建和销毁目标的唯一身份(ID)。如果检测结果与目标的IOU小于某个预定义的阈值(通常称为IOUmin),则不会将检测结果与目标相关联,这表示目标未被跟踪。此外,如果在连续TLost帧中没有检测到目标,跟踪将终止该目标的轨迹,其中TLost是一个可配置的参数。如果目标重新出现,跟踪将在新的身份下恢复。

2. DeepSORT算法

SORT在目标跟踪的精度和准确性方面表现出色,但它在生成大量不断切换的ID轨道和遇到遮挡情况时表现不佳。这是因为SORT使用关联矩阵来进行数据关联,而这种方法在复杂场景下存在一些限制。

DeepSORT是一种进化的跟踪算法,它改进了数据关联的方式,引入了更好的关联度量。DeepSORT可被定义为一种跟踪算法,它不仅仅基于目标的速度和运动来进行跟踪,还结合了目标的外观特征。

为了实现这些改进,DeepSORT首先在实际跟踪之前离线训练了一个具有出色区分性的特征嵌入网络。这个网络在大规模人员重新识别数据集上进行了训练,以确保在目标跟踪的上下文中具有高度区分性的特征。

在DeepSORT中,余弦距离度量方法用于训练深度关联度量模型。根据DeepSORT的论文,余弦距离考虑了目标的外观信息,这在处理遮挡和运动估计失败的情况下尤为有用。这意味着余弦距离是一种度量方法,有助于在目标长时间遮挡或其他复杂情况下准确恢复目标的身份。

四、Yolov8目标检测

1.算法简介

YOLOv8是一种基于图像全局信息进行预测并且它是一种端到端的目标检测系统,最初的YOLO模型由Joseph Redmon和Ali Farhadi于2015年提出,并随后进行了多次改进和迭代,产生了一系列不同版本的YOLO模型,如YOLOv2、YOLOv3、YOLOv4,YOLOv5等。这些更新和迭代旨在提高模型的性能、精度和速度,使其在实际应用中更具竞争力。

YOLOv8的核心思想是将图像划分为网格,并在每个网格单元中预测物体的边界框和类别。这种设计使得YOLO非常适合实时目标检测应用,因为它可以在较短的时间内完成目标检测任务。

2. 算法源码与部署

关于YOLOv8目标检测的相关内容可以看之前的博客:YoloV8目标检测与实例分割——目标检测onnx模型推理。

五、目标检测与追踪源码解析

1.检测

在每一帧中,目标检测器识别并提取出边界框(bbox),这些边界框表示在当前帧中检测到的目标物体。

 def detect(self,cv_src):
        boxes, scores, class_ids = self.detector(cv_src)

        pred_boxes = []
        for i in range(len(boxes)):
            x1,y1 = int(boxes[i][0]),int(boxes[i][1])
            x2,y2 = int(boxes[i][2]),int(boxes[i][3])
            lbl = class_names[class_ids[i]]
            # print(class_ids[i])

            # if lbl in ['person','sack','elec','bag','box','caron']:
            #     continue

            pred_boxes.append((x1,y1,x2,y2,lbl,class_ids[i]))

        return cv_src,pred_boxes

2. 生成detections

从这些检测到的边界框中,生成称为"detections"的目标检测结果。每个detection通常包含有关目标的信息,如边界框坐标和可信度分数。

#  deep_sort.py
def update(self, bbox_xywh, confidences, ori_img):
    self.height, self.width = ori_img.shape[:2]
    # 提取每个bbox的feature
    features = self._get_features(bbox_xywh, ori_img)
    # [cx,cy,w,h] -> [x1,y1,w,h]
    bbox_tlwh = self._xywh_to_tlwh(bbox_xywh)
    # 过滤掉置信度小于self.min_confidence的bbox,生成detections
    detections = [Detection(bbox_tlwh[i], conf, features[i]) for i,conf in enumerate(confidences) if conf > self.min_confidence]
    # NMS (这里self.nms_max_overlap的值为1,即保留了所有的detections)
    boxes = np.array([d.tlwh for d in detections])
    scores = np.array([d.confidence for d in detections])
    indices = non_max_suppression(boxes, self.nms_max_overlap, scores)
    detections = [detections[i] for i in indices]
    ...

3. 卡尔曼滤波预测

对于已知的跟踪对象(“tracks”),在下一帧中进行卡尔曼滤波预测,以估计其新的位置和速度。

#  track.py
def predict(self, kf):
    """Propagate the state distribution to the current time step using a 
       Kalman filter prediction step.
    Parameters
    ----------
    kf: The Kalman filter.
    """
    self.mean, self.covariance = kf.predict(self.mean, self.covariance)  # 预测
    self.age += 1  # 该track自出现以来的总帧数加1
    self.time_since_update += 1  # 该track自最近一次更新以来的总帧数加1

4.使用匈牙利算法将预测后的tracks和当前帧中的detections进行匹配

这是DeepSORT中的核心步骤。DeepSORT使用匈牙利算法来将预测的tracks和当前帧的detections进行匹配。这个匹配可以采用两种级联方法:首先,通过计算马氏距离来估算预测对象与检测对象之间的关联,如果马氏距离小于指定的阈值,则将它们匹配为同一目标。其次,DeepSORT还使用外观特征余弦距离度量,通过一个重识别模型获得不同物体的特征向量,然后构建余弦距离代价函数,以计算预测对象与检测对象的相似度。这两个代价函数的结果都趋向于小,如果边界框接近且特征相似,则将它们匹配为同一目标。

#  tracker.py
def _match(self, detections):
    def gated_metric(racks, dets, track_indices, detection_indices):
        """
        基于外观信息和马氏距离,计算卡尔曼滤波预测的tracks和当前时刻检测到的detections的代价矩阵
        """
        features = np.array([dets[i].feature for i in detection_indices])
        targets = np.array([tracks[i].track_id for i in track_indices]
 # 基于外观信息,计算tracks和detections的余弦距离代价矩阵
        cost_matrix = self.metric.distance(features, targets)
 # 基于马氏距离,过滤掉代价矩阵中一些不合适的项 (将其设置为一个较大的值)
        cost_matrix = linear_assignment.gate_cost_matrix(self.kf, cost_matrix, tracks, 
                      dets, track_indices, detection_indices)
        return cost_matrix

    # 区分开confirmed tracks和unconfirmed tracks
    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()]

    # 对confirmd tracks进行级联匹配
    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)

    # 对级联匹配中未匹配的tracks和unconfirmed tracks中time_since_update为1的tracks进行IOU匹配
    iou_track_candidates = unconfirmed_tracks + [k for k in unmatched_tracks_a if
                                                 self.tracks[k].time_since_update == 1]
    unmatched_tracks_a = [k for k in unmatched_tracks_a if
                          self.tracks[k].time_since_update != 1]
    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)
 
    # 整合所有的匹配对和未匹配的tracks
    matches = matches_a + matches_b
    unmatched_tracks = list(set(unmatched_tracks_a + unmatched_tracks_b))
    
    return matches, unmatched_tracks, unmatched_detections


# 级联匹配源码  linear_assignment.py
def matching_cascade(distance_metric, max_distance, cascade_depth, tracks, detections, 
                     track_indices=None, detection_indices=None):
    ...
    unmatched_detections = detection_indice
    matches = []
    # 由小到大依次对每个level的tracks做匹配
    for level in range(cascade_depth):
 # 如果没有detections,退出循环
        if len(unmatched_detections) == 0:  
            break
 # 当前level的所有tracks索引
        track_indices_l = [k for k in track_indices if 
                           tracks[k].time_since_update == 1 + level]
 # 如果当前level没有track,继续
        if len(track_indices_l) == 0: 
            continue
  
 # 匈牙利匹配
        matches_l, _, unmatched_detections = min_cost_matching(distance_metric, max_distance, tracks, detections, 
                                                               track_indices_l, unmatched_detections)
        
 matches += matches_l
 unmatched_tracks = list(set(track_indices) - set(k for k, _ in matches))
    return matches, unmatched_tracks, unmatched_detections

5. 卡尔曼滤波更新

匹配后,DeepSORT使用检测到的detections来更新每个已知的跟踪对象的状态,例如位置和速度。这有助于保持跟踪对象的准确性和连续性。

def update(self, detections):
    """Perform measurement update and track management.
    Parameters
    ----------
    detections: List[deep_sort.detection.Detection]
                A list of detections at the current time step.
    """
    # 得到匹配对、未匹配的tracks、未匹配的dectections
    matches, unmatched_tracks, unmatched_detections = self._match(detections)

    # 对于每个匹配成功的track,用其对应的detection进行更新
    for track_idx, detection_idx in matches:
        self.tracks[track_idx].update(self.kf, detections[detection_idx])
    
	# 对于未匹配的成功的track,将其标记为丢失
	for track_idx in unmatched_tracks:
        self.tracks[track_idx].mark_missed()
	
    # 对于未匹配成功的detection,初始化为新的track
    for detection_idx in unmatched_detections:
        self._initiate_track(detections[detection_idx])
    
	...

6.检测结果

目标追踪

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1184115.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

『 MySQL数据库 』数据库基础之库的基本操作

文章目录 库的操作创建数据库字符集与校验集那么该如何查看当前数据库默认的字符集与校验规则?查看数据库所支持的字符集与校验集不同字符集(校验集)之间的区别 基本操作查看数据库显式数据库创建语句数据库的修改数据库的删除数据库的备份检查连接 库的操作 创建数据库 CRE…

记一次 Android 周期性句柄泄漏的排查

滴滴国际化外卖 Android 商户端正常迭代版本过程中,新版本发布并且线上稳定一段时间后,突然触发线上 Crash 报警。 第一次排查发现是在依赖的底层平台 so 库中崩溃,经过沟通了解到其之前也存在过崩溃问题,所以升级相关底层 so 版本…

家居品牌怎么做小红书投放,寻找家居达人的方式有哪些?

在当今社交媒体的时代,找到优秀的家居博主并不困难。但是,在找家居行业博主的时候,了解家居行业特性就很重要,今天来为大家分享一下家居品牌怎么做小红书投放,寻找家居达人的方式有哪些? 一、家居行业特性 …

共享盘的文件删除后能找回吗

在当今高度信息化的时代,数据和文件的重要性日益凸显。然而,由于各种原因,我们有时会不小心删除了一些重要的文件,这时候就会面临数据恢复的问题。那么,对于共享盘的文件,删除后是否还能找回呢?…

conda环境下version libcublasLt.so.11 not defined问题解决

1 问题描述 运行模型训练&#xff0c;错误信息如下&#xff1a; Traceback (most recent call last):File "/opt/Bert-VITS2/./text/chinese_bert.py", line 3, in <module>import torchFile "/root/anaconda3/envs/vits/lib/python3.9/site-packages/t…

如何从存档服务器上完全删除PDM用户

当创建新用户时使用“PDM 登录”类型&#xff08;如下图&#xff09;&#xff0c;PDM用户名和密码会存储于存档服务器的注册表中。 存档服务器的注册表位置如下&#xff1a; HKEY_LOCAL_MACHINE\SOFTWARE\SolidWorks\Applications\PDMWorks Enterprise\ArchiveServer\ConisioU…

【Vue】组件封装小技巧 — 利用$attrs和v-bind接收传递未定义的属性

使用介绍 在Vue.js中&#xff0c;$attrs 和v-bind可以用于组件的二次封装&#xff0c;以在封装的组件中传递父组件的属性和事件。这对于创建高度可定制的通用组件非常有用。 下面是一些示例代码&#xff1a; 假设你有一个名为MyButton的自定义按钮组件&#xff0c;它接受一些…

Apipost发起请求,能正确返回,日志却打印java.io.EOFException: null 的原因

http响应头首部Content-Length - 程序员大本营 http响应头首部Content-Length HTTP Content-Length深入实践-CSDN博客 用了这么久HTTP, 你是否了解Content-Length?-CSDN博客 具体分析可看上面参考文章。 解决办法&#xff1a;可在请求头加上Content-Length&#xff0c;准确…

linux服务器添置一块新硬盘操作

之前有一台ubuntu服务器&#xff0c;考虑未来存储容量可能不够&#xff0c;添加了一块新的硬盘&#xff0c;这是本次添置硬盘过程。 首次接上硬盘&#xff0c;提示&#xff1a; 没有找到新接入设备&#xff0c;查看接线&#xff0c;主板有个硬盘接线端子坏了&#xff0c;更换一…

机器视觉opencv答题卡识别系统 计算机竞赛

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 答题卡识别系统 - opencv python 图像识别 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满分5分…

新翔绩效考核系统

介绍&#xff1a; 新翔绩效考核系统&#xff0c;是新翔软件有限公司整合众多企事业单位绩效考核需求&#xff0c;而开发的网络版绩效管理软件。软件分前台手机端评分页面和后台电脑端管理页面&#xff0c;可实现360度绩效考核、KPI考核等模式考核&#xff0c;评分方式多样、设…

计算机毕设 基于情感分析的网络舆情热点分析系统

文章目录 0 前言1 课题背景2 数据处理3 文本情感分析3.1 情感分析-词库搭建3.2 文本情感分析实现3.3 建立情感倾向性分析模型 4 数据可视化工具4.1 django框架介绍4.2 ECharts 5 Django使用echarts进行可视化展示5.1 修改setting.py连接mysql数据库5.2 导入数据5.3 使用echarts…

【网络面试必问(6)】IP协议对网络包的转发

接上一篇&#xff1a;【网络面试必问&#xff08;5&#xff09;】网络收发数据及断开服务器&#xff08;四次挥手&#xff09; 在之前的博客中&#xff0c;我们提到过&#xff0c;网络传输的报文是有真实的数据包和一些头部组成的&#xff0c;目前我们了解的头部就有TCP头、IP头…

VueUse、View Transitions API实现暗黑模式主题动画切换效果

VueUse、View Transitions API实现暗黑模式主题动画切换效果 前言View Transitions API兼容版本 VueUse 正题效果安装代码 作者GitHub&#xff1a;https://github.com/gitboyzcf 有兴趣可关注&#xff01;&#xff01; 前言 View Transitions API View Transitions API 是原生…

华东理工大学漏洞报送证书

获取来源&#xff1a;edusrc&#xff08;教育漏洞报告平台&#xff09; url&#xff1a;主页 | 教育漏洞报告平台 兑换价格&#xff1a;20金币 获取条件&#xff1a;提交华东理工大学任意中危或以上级别漏洞 证书规格&#xff1a;附送图二实物及封皮

[ Linux Busybox ] nandwrite 命令解析

文章目录 相关结构体nandwrite 函数实现nandwrite 实现流程图 文件路径&#xff1a;busybox-1.20.2/miscutils/nandwrite.c 相关结构体 MTD 相关信息结构体 struct mtd_info_user {__u8 type; // MTD 设备类型__u32 flags; // MTD设备属性标志__u32…

【Proteus仿真】【STM32单片机】水质监测报警系统设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真STM32单片机控制器&#xff0c;使用按键、LED、蜂鸣器、LCD1602、PCF8591 ADC、PH传感器、浑浊度传感器、DS18B20温度传感器、继电器模块等。 主要功能&#xff1a; 系统运行后&a…

汽车标定技术(七)--基于模型开发如何生成完整的A2L文件(2)

目录 1. 自定义ASAP2文件 2. asap2userlib.tlc需要修改的部分 3. 标定量观测量地址替换 3.1 由elf文件替换 3.2 由map文件替换 3.3 正则表达式&#xff08;含asap2post.m修改方法&#xff09; 4.小结 书接上文汽车标定技术(五)--基于模型开发如何生成完整的A2L文件(1)-C…

考研408-计算机网络 第二章-物理层学习笔记及习题

第二章 物理层 一 通信基础 1.1 物理层基本概念 1.1.1 认识物理层 物理层目的&#xff1a;解决如何在连接各种计算机的传输媒体上传输数据比特流&#xff0c;而不是具体的传输媒体。 物理层主要任务&#xff1a;确认与传输媒体接口有关的一些特性&#xff0c;需要进行定义标…

Kafka(消息队列)--简介

1、kafka&#xff1a; 是一个高吞吐的分布式消息系统&#xff0c;与Hdfs比较相似&#xff0c;但是与hdfs的区别是在于hdfs是存储的是历史的、海量的数据&#xff0c;然而kafka存储的是实时的、最新的数据。 2、消息队列&#xff1a; 指的是在Kafka中的数据队列。可以存放数据在…