【Datawhale AI夏令营第五期】 CV方向 Task02学习笔记 精读Baseline 建模方案解读与进阶

news2024/9/20 22:46:46

【Datawhale AI夏令营第五期】 CV方向 Task02学习笔记 精读Baseline 建模方案解读与进阶

教程:

链接:
https://linklearner.com/activity/16/16/68
传送门
之前我看原画课的时候,造型的部分就跟我们说,让我们日常观察事物的时候把它想象出有个外边框。在画室学画的期间,第一步打型也是先在纸上草拟最上下左右的几个关键点。
在这里插入图片描述
可以理解为分类器只需要输出一个最正确的答案,但是检测器需要同时输出所有合理的答案?
在这里插入图片描述
在这里插入图片描述

物体检测算法主要分为两类:One-Stage(一阶段)和Two-Stage(两阶段)模型。
在这里插入图片描述
一步到位:全盘扫描,简单粗暴速度快。
两步战略:先抓可疑区域,再精细排查,准确精度高。
在这里插入图片描述
具体选择?还是要看模型的应用场景。在这里插入图片描述
Yolo适合要求速度的:在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
认同,高频亮眼的是YOLO5,YOLO8。
在这里插入图片描述
一图一个txt文件,一行标注一个物体,包括类别索引和边界框。
YOLO习惯看的数据是
中心坐标+长宽比例
。所以需要对原本坐标在左上角,宽高是长度的数据集做处理。
在这里插入图片描述
在这里插入图片描述
在Baseline中就有类别列表和需要识别的违规行为数量。
在这里插入图片描述

# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
path: ../dataset/  # dataset root dir
train: images/train/  # train images (relative to 'path') 128 images
val: images/val/  # train images (relative to 'path') 128 images

# Classes
nc: 2  # number of classes
names: ["0", '1']  # class names

我记得训练模型好像还有个best.pt的说法,是训练完成后模型保存的最佳权重,一般就用这个best.pt来执行后续的工作。
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
results和weight应该比较重要,跟混淆矩阵相关的这几个F1,RP啥的图表根据需要看,我记得这几个指标好像别的地方见过有函数可以直接打印输出。
在这里插入图片描述
在这里插入图片描述

from sklearn.metrics import confusion_matrix, classification_report, roc_curve, auc

# 假设 y_true 是真实标签,y_pred 是模型预测的标签
y_true = [0, 1, 0, 1]
y_pred = [0, 1, 1, 0]

# 计算混淆矩阵
conf_matrix = confusion_matrix(y_true, y_pred)

# 打印分类报告,其中包含了精确度、召回率和F1分数
print(classification_report(y_true, y_pred))

# 计算ROC曲线和AUC
fpr, tpr, thresholds = roc_curve(y_true, y_pred)
roc_auc = auc(fpr, tpr)

# 打印AUC值
print("AUC:", roc_auc)

此外,还可以使用 matplotlib 或 seaborn 等可视化库来绘制混淆矩阵和ROC曲线:

import matplotlib.pyplot as plt
import seaborn as sns

# 绘制混淆矩阵热力图
sns.heatmap(conf_matrix, annot=True, fmt='d')
plt.show()

# 绘制ROC曲线
plt.plot(fpr, tpr, label='ROC curve (area = %0.2f)' % roc_auc)
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic')
plt.legend(loc="lower right")
plt.show()

下面这个点是我第一次看,以后多加留心。
在这里插入图片描述
在这里插入图片描述
选择YOLO的原因应该是这个最后的应用场景类似于监控摄像头,不要求很精确,但是必须实时检测,快准狠,反应迅速。在这里插入图片描述
如果毕设答辩选了YOLO视频图像识别啥的,下面教程的这段话应该可以借鉴思路,一下子多了好几行。在这里插入图片描述
顺便,这放一张搞笑梗图:
在这里插入图片描述

Baseline 进阶思路:

1.加数据量。2.换模型。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

原始为
!wget http://mirror.coggle.club/yolo/yolov8n-v8.2.0.pt -O yolov8n.pt

下面任意一个
!wget http://mirror.coggle.club/yolo/yolov8s-v8.2.0.pt -O yolov8s.pt
!wget http://mirror.coggle.club/yolo/yolov8m-v8.2.0.pt -O yolov8m.pt
!wget http://mirror.coggle.club/yolo/yolov8l-v8.2.0.pt -O yolov8l.pt
!wget http://mirror.coggle.club/yolo/yolov8x-v8.2.0.pt -O yolov8x.pt

我这就试试多放几个数据喂模型,这是我第一次跑Baseline的结果,泯然众人。
在这里插入图片描述
我给他安排15个视频依葫芦画瓢:
在这里插入图片描述
下载了zip文件以后,解压json这步厚德云很成功,上一期的阿里云实例就不行,代码一点没动过,一样是git命令拉下来的,我不知道为什么。
在这里插入图片描述
结果文件夹还没出,先看看训练的result——????这啥啊??在这里插入图片描述
看这个图倒是感觉检测得还挺准?话说他怎么知道是不是违章停车呢?会不会把正常停车也标出来,本质上是个车就要逮呢??
在这里插入图片描述
一看得分,我靠,效果拔群啊??!
在这里插入图片描述
在这里插入图片描述
不知道是触发了什么神奇开关,有机会的话我再多试试。

应该看不到哪去但是也搬来的教程参考资料:

https://docs.ultralytics.com/datasets/detect/#ultralytics-yolo-format
https://docs.ultralytics.com/guides/yolo-performance-metrics/
https://docs.ultralytics.com/models/yolov8/#performance-metrics

精读Baseline:

把Task01的小试牛刀体验代码跑了,我对这其中的细节很好奇,因为我之前自己跑过别人分享的Yolo5项目,当时感觉是特别大的一个文件夹,里面塞满了需要用到的各类东西,但是这个代码只需要短短几行就可以了。
之前我只听过F1-score,这个跟混淆矩阵有关系,但这个MOTA指标是啥?
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下载数据集,并且还指定了下载的名字。
在这里插入图片描述
在这里插入图片描述
我还是第一次注意到read_json这个函数:在这里插入图片描述
读取视频的一帧测试一下:
在这里插入图片描述
我感觉Kimi说的有道理,这个逻辑读了第一帧会break,啥也没读到也是break,那该如何区分是哪种情况呢?起码该有个输出??
在这里插入图片描述
在这里插入图片描述
因为如果不看是否ret确实读到了视频第一帧的话,下一个frame.shape的代码可能就会遇到报错。在这里插入图片描述
在这里插入图片描述
所以为什么返回的帧数还可能是浮点数呢?
在这里插入图片描述
先简单拉个框看看效果:在这里插入图片描述
在这里插入图片描述
既然这段代码实现的功能是在图片上拉个能指定(颜色,边框粗细,大小,四角点)的框,那么市面上那些图像标注工具,是不是核心逻辑就跟这个差不多呢?
在这里插入图片描述
关于市面上免费的图像标注工具,我之前的帖子里面记了几个:
https://blog.csdn.net/bailichen800/article/details/140308080
传送门

表示目录路径的方法:

感觉这个会比较通用,码住。

在这里插入图片描述
在这里插入图片描述

import os

# 获取当前目录的绝对路径,并确保路径以分隔符结尾
dir_path = os.path.join(os.path.abspath('./'), '')

print(dir_path)

在这里插入图片描述

dir_path = os.path.abspath('.')
# 连接目录路径和文件名
file_path = os.path.join(dir_path, 'example.txt')

这个具体情况再慢慢print出路径调整吧,先暂时把大概函数记住。

打开yaml文件并写入:

这段代码本质上是遵循了读写文本文件的基本流程,所以操作大同小异。

# 需要按照你的修改path
with open('yolo-dataset/yolo.yaml', 'w', encoding='utf-8') as up:
    up.write(f'''
path: {dir_path}/yolo-dataset/
train: train/
val: val/

names:
    0: 非机动车违停
    1: 机动车违停
    2: 垃圾桶满溢
    3: 违法经营
''')

在这里插入图片描述
glob模块获取指定名称的标注文件和视频文件,放入列表,并且排序,确保对应关系。在这里插入图片描述
在这里插入图片描述
下面这段代码看着比较复杂:

for anno_path, video_path in zip(train_annos[:5], train_videos[:5]): #使用 zip 函数将 train_annos 和 train_videos 列表的前5个元素配对。这意味着代码将同时处理每个标注文件和对应的视频文件
    print(video_path) 
    anno_df = pd.read_json(anno_path) #使用 pandas 的 read_json 函数读取标注文件(.json 格式),并将结果存储在 anno_df DataFrame 中
    cap = cv2.VideoCapture(video_path) #使用 cv2.VideoCapture 打开视频文件
    frame_idx = 0  
    while True:
        ret, frame = cap.read() #使用 cap.read() 在一个循环中逐帧读取视频。如果读取失败(ret 为 False),则跳出循环
        if not ret:
            break
 
        img_height, img_width = frame.shape[:2] #从当前帧中获取高度和宽度
        
        frame_anno = anno_df[anno_df['frame_id'] == frame_idx] #使用 anno_df 中的 frame_id 筛选出当前帧的标注信息
        cv2.imwrite('./yolo-dataset/train/' + anno_path.split('/')[-1][:-5] + '_' + str(frame_idx) + '.jpg', frame) #将当前帧保存为JPEG图像,文件名基于标注文件名和帧索引

        if len(frame_anno) != 0:  #如果存在当前帧的标注信息,使用 with open 打开一个文本文件进行写入。文本文件名基于标注文件名和帧索引
            with open('./yolo-dataset/train/' + anno_path.split('/')[-1][:-5] + '_' + str(frame_idx) + '.txt', 'w') as up:
                for category, bbox in zip(frame_anno['category'].values, frame_anno['bbox'].values):
                    category_idx = category_labels.index(category)
                    #对于每个标注,将原始的边界框坐标(bbox)转换为 YOLO 格式的相对坐标和尺寸。YOLO 格式使用中心点坐标和宽度、高度来表示边界框。
                    x_min, y_min, x_max, y_max = bbox
                    x_center = (x_min + x_max) / 2 / img_width
                    y_center = (y_min + y_max) / 2 / img_height
                    width = (x_max - x_min) / img_width
                    height = (y_max - y_min) / img_height

                    if x_center > 1:#如果 x_center 大于1(这通常不应该发生,因为坐标应该在0到1之间),打印出边界框坐标。
                        print(bbox)
                    up.write(f'{category_idx} {x_center} {y_center} {width} {height}\n') #将转换后的标注信息写入文本文件。每个标注一行,包含类别索引和转换后的坐标、宽度、高度。
        
        frame_idx += 1

在这里插入图片描述
但我感觉有点抽象,他这一顿操作到底在干啥??
原来是在适应Yolo的需求,尤其是这个矩形框的表示形式。在这里插入图片描述
下载文件并保存到指定目录:注意这个-p和-o的参数。

!mkdir -p ~/.config/Ultralytics/
!wget http://mirror.coggle.club/yolo/Arial.ttf -O ~/.config/Ultralytics/Arial.ttf

在这里插入图片描述

使用 Ultralytics 的 YOLO(You Only Look Once)目标检测模型进行训练的:

import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0" #指定了 CUDA 应该使用的第一个 GPU 设备。在这个例子中,它被设置为 "0",意味着使用默认的 GPU 设备

import warnings
warnings.filterwarnings('ignore') #忽略所有的警告信息,以避免在训练过程中输出不必要的警告


from ultralytics import YOLO #从 Ultralytics 库导入 YOLO 类
model = YOLO("yolov8n.pt") #创建了一个 YOLO 模型实例,使用预训练的权重文件 yolov8n.pt
results = model.train(data="yolo-dataset/yolo.yaml", epochs=2, imgsz=1080, batch=16) #启动了模型的训练过程

注意指定默认GPU设备、忽略所有的警告信息的方法,以后其他代码可以复用:
在这里插入图片描述

使用 Ultralytics 的 YOLO 模型对视频文件进行目标检测,并将检测结果保存为 JSON 格式的文件:

from ultralytics import YOLO
model = YOLO("runs/detect/train/weights/best.pt")
import glob

for path in glob.glob('测试集/*.mp4'):
    submit_json = []
    results = model(path, conf=0.05, imgsz=1080,  verbose=False)
    for idx, result in enumerate(results):
        boxes = result.boxes  # Boxes object for bounding box outputs
        masks = result.masks  # Masks object for segmentation masks outputs
        keypoints = result.keypoints  # Keypoints object for pose outputs
        probs = result.probs  # Probs object for classification outputs
        obb = result.obb  # Oriented boxes object for OBB outputs

        if len(boxes.cls) == 0:
            continue
        
        xywh = boxes.xyxy.data.cpu().numpy().round()
        cls = boxes.cls.data.cpu().numpy().round()
        conf = boxes.conf.data.cpu().numpy()
        for i, (ci, xy, confi) in enumerate(zip(cls, xywh, conf)):
            submit_json.append(
                {
                    'frame_id': idx,
                    'event_id': i+1,
                    'category': category_labels[int(ci)],
                    'bbox': list([int(x) for x in xy]),
                    "confidence": float(confi)
                }
            )

    with open('./result/' + path.split('/')[-1][:-4] + '.json', 'w', encoding='utf-8') as up:
        json.dump(submit_json, up, indent=4, ensure_ascii=False)

在这里插入图片描述
首先看第一个问题,这个“最小置信度阈值”是什么呢?
也就是说,给模型对自己的答案定一个信心标准,达到这个标准的才计数考核模型的预测水平。如果模型都是瞎猜给的答案,直接当无效结果考虑。
我感觉就像有些问卷调查里面的“弱智问题”的作用,故意问“1+1=?”,“C选项是什么颜色”这种很简单的,就是要看这份问卷有没有被认真作答。如果这些选项都选错得话说明是瞎填的,可以直接作废了。
在这里插入图片描述
这几个提取的信息里边谁是啥得看一眼,以后应该用得多:在这里插入图片描述

    for idx, result in enumerate(results): #从结果中提取边界框、分割掩码、关键点、概率和旋转边界框不同类型的检测输出。,,,,
        boxes = result.boxes  #boxes 通常包含边界框信息
        masks = result.masks  # masks 包含实例分割的掩码
        keypoints = result.keypoints  # keypoints 包含关键点检测结果
        probs = result.probs  # probs 包含每个检测到的对象的类别概率
        obb = result.obb  #obb 包含旋转边界框(Oriented Bounding Box)信息

在这里插入图片描述

from ultralytics import YOLO
model = YOLO("runs/detect/train/weights/best.pt") #创建一个 YOLO 模型实例,并加载预训练的权重文件 best.pt
import glob

for path in glob.glob('测试集/*.mp4'): #用于文件名模式匹配,获取符合特定规则的文件列表 获取测试集目录下所有 .mp4 视频文件的路径,并逐个进行处理
    submit_json = [] #存储所有检测结果
    results = model(path, conf=0.05, imgsz=1080,  verbose=False) #使用模型对每个视频文件进行检测,设置最小置信度阈值 conf=0.05,图像尺寸 imgsz=1080,以及 verbose=False 表示不打印详细输出
    for idx, result in enumerate(results): #从结果中提取边界框、分割掩码、关键点、概率和旋转边界框不同类型的检测输出。,,,,
        boxes = result.boxes  #boxes 通常包含边界框信息
        masks = result.masks  # masks 包含实例分割的掩码
        keypoints = result.keypoints  # keypoints 包含关键点检测结果
        probs = result.probs  # probs 包含每个检测到的对象的类别概率
        obb = result.obb  #obb 包含旋转边界框(Oriented Bounding Box)信息

        if len(boxes.cls) == 0:  #如果当前帧没有检测到任何对象(len(boxes.cls) == 0),则跳过当前帧
            continue
        
        xywh = boxes.xyxy.data.cpu().numpy().round() #从 boxes.xyxy 提取的边界框坐标,表示为 (x, y, w, h) 格式,其中 x, y 是边界框左上角的坐标,w, h 是边界框的宽度和高度
        cls = boxes.cls.data.cpu().numpy().round()  #cls 是从 boxes.cls 提取的类别索引
        conf = boxes.conf.data.cpu().numpy() #conf 是从 boxes.conf 提取的置信度。
        for i, (ci, xy, confi) in enumerate(zip(cls, xywh, conf)):
            submit_json.append(  #为每个检测到的对象构建一个字典,包含帧 ID、事件 ID、类别、边界框坐标和置信度。
                {
                    'frame_id': idx,
                    'event_id': i+1,
                    'category': category_labels[int(ci)],
                    'bbox': list([int(x) for x in xy]),
                    "confidence": float(confi)
                }
            )

    with open('./result/' + path.split('/')[-1][:-4] + '.json', 'w', encoding='utf-8') as up:
        json.dump(submit_json, up, indent=4, ensure_ascii=False) #将 submit_json 列表写入到结果目录下,文件名为原始视频文件名加上 .json 后缀。

在这里插入图片描述
ci等于0,1,2,3时,在之前这个定义这个列表里面找对应的违规行为类别,把汉字代替数字存进JSON文件里。在这里插入图片描述

        xywh = boxes.xyxy.data.cpu().numpy().round() #从 boxes.xyxy 提取的边界框坐标,表示为 (x, y, w, h) 格式,其中 x, y 是边界框左上角的坐标,w, h 是边界框的宽度和高度
        cls = boxes.cls.data.cpu().numpy().round()  #cls 是从 boxes.cls 提取的类别索引
        conf = boxes.conf.data.cpu().numpy() #conf 是从 boxes.conf 提取的置信度

输出result:

!\rm result/.ipynb_checkpoints/ -rf
!\rm result.zip
!zip -r result.zip result/

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

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

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

相关文章

海运系统:海运拼箱 小批量货物的海运奥秘

在国际海运运输的广阔领域中,海运拼箱作为一种灵活且经济的运输方式,尤其适用于那些货物量不大或体积不足以单独填满一个标准集装箱的场景。这种运输模式不仅促进了国际贸易的便捷性,还通过资源共享的方式,有效降低了物流成本&…

p10 容器的基本命令

首先先拉取一个centos的镜像 命令:docker pull centos 新建容器并且启动 这里直接参考老师的命令吧 接下来是启动并且进入到容器当中去输入docker run -it centos /bin/bash这里是以交互的方式进入到容器中可以看到接下来的ls命令输出的东西就是一个Linux系统最…

Ansys Speos | 挡风玻璃光学畸变分析

附件下载 联系工作人员获取附件 此示例介绍了基于 TL 957 标准和43号法规(ECE R43)的挡风玻璃光学畸变分析的工作流程,以及 GitHub Ansys 光学自动化中提供的分析自动化工具。 如果您从未使用过任何 GitHub 仓库,可以根据光学自…

数据结构(邓俊辉)学习笔记】串 07——KMP算法:分摊分析

文章目录 1.失之粗糙2.精准估计 1.失之粗糙 以下,就来对 KMP 算法的性能做一分析。我们知道 KMP 算法的计算过程可以根据对齐位置相应的分为若干个阶段,然而每一个阶段所对应的计算量是有很大区别的。很快就会看到,如果只是简单地从最坏的角…

K8S的持久化存储

文章目录 一、持久化存储emptyDir实际操作 hostPath建立过程 NFS存储NFS 存储的优点NFS 存储的缺点具体操作 pv和pvcPersistent Volume (PV)使用场景 Persistent Volume Claim (PVC)使用场景 使用 PV 和 PVC 的场景实际操作 StorageClassStorageClass 概述应用场景实际应用 一、…

实用攻略:亲身试用,高效数据恢复软件推荐!

今天要跟大家分享一下我使用几款数据恢复软件的经历。如果你曾经丢失过重要的文件,那除了注意备份外,也可以尝试一下这些非常棒的免费数据恢复软件! 第一款:福昕数据恢复 链接:www.pdf365.cn/foxit-restore/ 首先聊…

Nginx+ModSecurity(3.0.x)安装教程及配置WAF规则文件

本文主要介绍ModSecurity v3.0.x在Nginx环境下的安装、WAF规则文件配置、以及防御效果的验证,因此对于Nginx仅进行简单化安装。 服务器操作系统:linux 位最小化安装 一、安装相关依赖工具 Bash yum install -y git wget epel-release yum install -y g…

大模型企业应用落地系列二》基于大模型的对话式推荐系统》核心技术架构设计图

注:此文章内容均节选自充电了么创始人,CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》(人工智能科学与技术丛书)【陈敬雷编著】【清华大学出版社】 文章目录 大模型企业应用落地系列二基于大模型的对话式推荐系统》心技术架…

【精品】计算机毕业设计之:springboot游戏分享网站(源码+文档+辅导)

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

win11,vscode上用docker环境跑项目

1.首先用dockerfile创建docker镜像 以下是dockerfile文件的内容: FROM pytorch/pytorch:1.11.0-cuda11.3-cudnn8-devel LABEL Service"SparseInstanceActivation"ENV TZEurope/Moscow ENV DETECTRON_TAGv0.6 ARG DEBIAN_FRONTENDnoninteractiveRUN apt-…

JavaScript:js;知识回顾;笔记分享

一,js前奏 1,js简介: Javascript是一种由Netscape(网景)的LiveScript发展而来的原型化继承的面向对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如Perl,遗留的速度问题&a…

数据结构与算法(1)

抽象数据类型定义 算法的效率 时间效率 一个算法的运行时间是指一个算法在计算机上运行所耗费的时间 大致可以等于计算机执行一种简单的操作(如赋值、比较、移动等) 所需的时间与算法中进行的简单操作次数乘积。 比较时间复杂度(看数量级) 空…

【STM32】RTC

忠实的时间记录者——RTC,板子断电也能继续记录(当然,得有纽扣电池供电)。 大部分图片来源:正点原子HAL库课程 专栏目录:记录自己的嵌入式学习之路-CSDN博客 目录 1 概述 2 应用 3 RTC方案 4 …

javacv-ffmpeg ProcessBuilder批量旋转图片

javacv-ffmpeg ProcessBuilder实现对图片的旋转,最近需要处理很多图片,量有点多,所以不能一个一个去编辑旋转图片,所以写一个工具类,实现对图片的旋转 maven配置文件,加上对ffmpeg的依赖,由于f…

关于自定义控件,头文件找不到问题的解决办法

在ui文件中使用控件提升的时候,突然发现ui_xxxx.h竟然报错了, 这在之前是没有碰到过,苦思过后认为是环境变量的问题,因为现在正在用的构建套件是 mingw 的,但在此之前我一直用的是msvc,并且环境变量的配置…

骑行耳机该怎么选?精选南卡、骨聆、小米多款顶尖实用品牌!

骨传导耳机,作为运动骑行领域的黑科技伴侣,以其独特的传音方式,让众多骑行运动爱好者在享受音乐的同时,依然能清晰感知外界环境,提升运动安全与乐趣。然而,随着骨传导耳机热度增加,市面上开始出…

Prometheus监控Kubernetes ETCD

文章目录 一、kubeadm方式部署etcd1.修改etcd指标接口监听地址2.prometheus中添加etcd的服务发现配置3.创建etcd的service4.grafana添加etcd监控模版 二、二进制方式部署k8s etcd1.将etcd服务代理到k8s集群2.创建etcd证书的secrets3.prometheus挂载etcd证书的secrets4.promethe…

63. 不同路径 II -dp7

63. 不同路径 IIhttps://leetcode.cn/problems/unique-paths-ii/ 输入:obstacleGrid [[0,0,0],[0,1,0],[0,0,0]] 输出:2 解释:3x3 网格的正中间有一个障碍物。 从左上角到右下角一共有 2 条不同的路径: 1. 向右 -> 向右 ->…

Chrome 中的 RCE 会在 JIT 编译器中产生不正确的副作用

此类漏洞通常是“一键式”攻击的起点,当受害者访问恶意网站时,该漏洞会危害受害者的设备。Chrome 中的渲染器 RCE 允许攻击者危害 Chrome 渲染器进程并执行任意代码。但是,渲染器进程的权限有限,因此攻击者需要将此类漏洞与第二个“沙盒逃逸”漏洞串联起来:Chrome 浏览器进…

C#WinFrom 中实现可自定义按钮和事件的消息提示框

实现效果: public partial class CustomMessageBox : Form {// 声明按钮和标签控件private Button btnOption1;private Button btnOption2;private Label lblMessage;// 自定义属性用于获取对话框的结果public DialogResult DialogResult1 { get; private set; }// …