labelme目标检测数据类型转换

1. labelme数据类型

LabelMe是一个开源的在线图像标注工具,旨在帮助用户创建和标记图像数据集。它提供了一个用户友好的界面,让用户可以直观地在图像上绘制标记框、多边形、线条等,以标识和注释图像中的对象或区域。
GitHub:https://github.com/wkentaro/labelme

labelme格式

经过labelme标注工具对图像中的目标进行标注之后,可以得到如下的标注json文件。在这里插入图片描述
在这里我们主要关注目标框的格式,其中shapes字段中包含所有的目标内容,每个目标框的位置信息可以通过points字段进行获取,是一个两行两列的二维数组,如同:

[[a,b],[c,d]
]

其中a,b代表左上角点位置,c,d表示右下角点位置,如下图所示。
在这里插入图片描述

目标框可视化

对于labelme格式的数据,可以直接使用labelme标注工具打开进行查看,同样这里也给出python的可视化代码,方便大家直接画图进行查看。


import numpy as np
import os
import cv2
import jsondef display(img_path, bboxes, save_path,opencv=True):"""_summary_Args:img_path (str): 图像路径bboxes (numpy): 二维数组,其中每一行表示一个目标框,顺序为(xmin, ymin, xmax, ymax)opencv (bool): 是否使用opencv"""if opencv:color = (0, 0, 255)img_data = cv2.imread(img_path)for box in bboxes:xmin, ymin, xmax, ymax = np.array(box, dtype=np.int32)cv2.rectangle(img_data, (xmin, ymin), (xmax, ymax),color, 2)cv2.imwrite(save_path, img_data)else:from PIL import Image, ImageDrawcolor = (255, 0, 0)img_data = Image.open(img_path).convert("RGB")draw = ImageDraw.Draw(img_data)for box in bboxes:xmin, ymin, xmax, ymax = np.array(box, dtype=np.int32)draw.rectangle([xmin, ymin, xmax, ymax], outline=color)img_data.save(save_path)def vis_labelme(img_root, json_root, save_root):"""_summary_Args:img_root (str): 图像数据的主路径json_root (str): 标签数据的主路径save_root (str): 可视化图像保存路径"""from pathlib import Pathjson_files = Path(json_root).glob("./*.json")for json_path in json_files:anno= json.load(open(str(json_path), "r", encoding="utf-8"))shapes = anno['shapes']name = json_path.stemimg_path = Path(img_root) / f"{name}.jpg"if img_path.is_file():bboxes = list()for s in shapes:pts = s['points']x1, y1 = pts[0]x2, y2 = pts[1]bboxes.append([x1, y1, x2, y2])save_path = os.path.join(save_root, img_path.name)display(str(img_path), bboxes, save_path)if __name__ == "__main__":img_root = "labelme"json_root = "labelme"save_root = "vis_labelme"vis_labelme(img_root, json_root, save_root)

2. 与yolo之间的转换

YOLO(You Only Look Once)是一种流行的目标检测算法,其特点是能够实时地识别图像中的目标物体。YOLO格式是指用于标注目标检测数据集的标签格式。

在YOLO格式中,每个图像的标签数据通常存储在一个单独的文本文件中,与图像文件具有相同的名称。

yolo格式

每个标签文件包含一行或多行文本,每行描述一个目标物体的位置和类别。每行的格式如下:

<class> <x_center> <y_center> <width> <height>
  • <class> 表示目标物体的类别,通常是一个整数。例如,如果数据集包含车辆、行人和自行车三个类别,可以用0表示车辆,1表示行人,2表示自行车。
  • <x_center><y_center> 是目标物体边界框的中心坐标,相对于图像的宽度和高度。这些值的范围是0到1之间,表示相对位置。
  • <width><height> 是目标物体边界框的宽度和高度,相对于图像的宽度和高度。同样,这些值的范围也是0到1之间

例如,假设我们有一个图像中包含一辆车的标签数据,车辆在图像中的位置为(100,200),宽度为50,高度为30。如果图像的宽度是500,高度是400,那么对应的YOLO格式标签数据将是:

0 0.25 0.5 0.1 0.075

使用YOLO格式的标签数据可以方便地与YOLO模型进行训练和推断,从而实现目标检测任务。

labelme转yolo

以下是labelme转换yolo格式的脚本,需要制定labelme和yolo数据集的主路径,此外还需要一个数据集类别的txt文件。

import os
import json
import shutil
import numpy as np
from pathlib import Pathdef get_categories(cls_path):assert(os.path.exists(cls_path)), f"cannot find classes file"with open(cls_path) as f:data = f.readlines()name2idx = dict()for idx, cls in enumerate(data):name2idx[cls.strip()] = idxreturn name2idxdef labelme2yolo_single(label_file, cls2id):anno= json.load(open(label_file, "r", encoding="utf-8"))shapes = anno['shapes']w0, h0 = anno['imageWidth'], anno['imageHeight']image_path = os.path.basename(anno['imagePath'])labels = []for s in shapes:pts = s['points']x1, y1 = pts[0]x2, y2 = pts[1]x = (x1 + x2) / 2 / w0 y = (y1 + y2) / 2 / h0w  = abs(x2 - x1) / w0h  = abs(y2 - y1) / h0cid = cls2id[s['label']]        labels.append([cid, x, y, w, h])return labels, image_pathdef labelme2yolo(labelme_dir, yolo_dir, cls_path):labelme_img_dir = Path(labelme_dir) labelme_label_dir = Path(labelme_dir)yolo_img_dir = Path(yolo_dir) / "images/"yolo_label_dir = Path(yolo_dir) / 'labels/'if not yolo_img_dir.exists():yolo_img_dir.mkdir(parents=True, exist_ok=True)if not yolo_label_dir.exists():yolo_label_dir.mkdir(parents=True, exist_ok=True)json_files = labelme_label_dir.glob("./*.json")cls2id = get_categories(cls_path)for ijf, jf in enumerate(json_files):filename = jf.stemlabels, image_path = labelme2yolo_single(jf, cls2id)# if len(labels) > 0:# np.savetxt(yolo_label_dir + filename + '.txt', labels)shutil.copy(str(labelme_img_dir / image_path), str(yolo_img_dir / image_path))txt_path = str(yolo_label_dir / f"{filename}.txt")with open(txt_path, 'w') as f:for cls, *xywhn in reversed(labels):line = (cls, *xywhn)f.write(('%g ' * len(line)).rstrip() % line + '\n')print(f" {ijf} {str(jf)}")print('Completed!')if __name__ == '__main__':labelme_root = r'labelme'yolo_root = r'yolo'cls_path = "yolo/classes.txt"labelme2yolo(labelme_root, yolo_root, cls_path)

yolo转labelme

同样,有时候我们可以以labelme数据格式作为中间格式,然后把labelme格式转换为其他格式,或者我们需要对yolo目标检测算法的结果进行微调,因此,这里也提供了yolo转labelme的脚本。

import cv2
import os
import json
import shutil
import numpy as npdef get_categories(cls_path):assert(os.path.exists(cls_path)), f"cannot find classes file"with open(cls_path) as f:data = f.readlines()idx2name = dict()for idx, cls in enumerate(data):idx2name[idx] = cls.strip()return idx2namedef xyxy2labelme(labels, w, h, image_path, save_dir, id2cls):if not os.path.exists(save_dir):os.makedirs(save_dir)label_dict = {}label_dict['version'] = '5.0.1'label_dict['flags'] = {}label_dict['imageData'] = Nonelabel_dict['imagePath'] = image_pathlabel_dict['imageHeight'] = hlabel_dict['imageWidth'] = wlabel_dict['shapes'] = []for l in labels:tmp = {}tmp['label'] = id2cls[int(l[0])]tmp['points'] =[[l[1], l[2]], [l[3], l[4]]]tmp['group_id']= Nonetmp['shape_type'] = 'rectangle'tmp['flags'] = {}label_dict['shapes'].append(tmp)    fn = os.path.join(save_dir,image_path.rsplit('.', 1)[0]+'.json')with open(fn, 'w') as f:json.dump(label_dict, f, ensure_ascii=False, indent=2)def yolo2labelme(yolo_dir, save_dir, cls_path):yolo_image_dir = os.path.join(yolo_dir, "images")yolo_label_dir = os.path.join(yolo_dir, "labels")id2cls = get_categories(cls_path)image_files = os.listdir(yolo_image_dir)for iimgf, imgf in enumerate(image_files):print(iimgf+1, '/', len(image_files), imgf)fn = imgf.rsplit('.', 1)[0]image = cv2.imread(os.path.join(yolo_image_dir, imgf))h,w = image.shape[:2]shutil.copyfile(os.path.join(yolo_image_dir, imgf), os.path.join(save_dir, imgf))if not os.path.exists(os.path.join(yolo_label_dir, fn + '.txt')):continuelabels = np.loadtxt(os.path.join(yolo_label_dir, fn + '.txt')).reshape(-1, 5)if len(labels) < 1:passelse:labels[:,1::2] = w * labels[:, 1::2]labels[:,2::2] = h * labels[:, 2::2]labels_xyxy = np.zeros(labels.shape)labels_xyxy[:, 1] = np.clip(labels[:, 1] - labels[:, 3]/2, 0, w)labels_xyxy[:, 2] = np.clip(labels[:, 2] - labels[:, 4]/2, 0, h)labels_xyxy[:, 3] = np.clip(labels[:, 1] + labels[:, 3]/2, 0, w)labels_xyxy[:, 4] = np.clip(labels[:, 2] + labels[:, 4]/2, 0, h)xyxy2labelme(labels_xyxy, w, h, imgf, save_dir, id2cls)print('Completed!')if __name__ == '__main__':yolo_dir = "yolo"save_dir = "labelme"cls_path = "yolo/classes.txt"yolo2labelme(yolo_dir, save_dir, cls_path)

可视化

与labelme可视化一样,只需要解析yolo格式的标签文件,然后传入到display函数中即可。


import numpy as np
import os
import cv2
from pathlib import Path
import copydef display(img_path, bboxes, save_path,opencv=True):"""_summary_Args:img_path (str): 图像路径bboxes (numpy): 二维数组,其中每一行表示一个目标框,顺序为(xmin, ymin, xmax, ymax)opencv (bool): 是否使用opencv"""if opencv:color = (0, 0, 255)img_data = cv2.imread(img_path)for box in bboxes:xmin, ymin, xmax, ymax = np.array(box, dtype=np.int32)cv2.rectangle(img_data, (xmin, ymin), (xmax, ymax),color, 2)cv2.imwrite(save_path, img_data)else:from PIL import Image, ImageDrawcolor = (255, 0, 0)img_data = Image.open(img_path).convert("RGB")draw = ImageDraw.Draw(img_data)for box in bboxes:xmin, ymin, xmax, ymax = np.array(box, dtype=np.int32)draw.rectangle([xmin, ymin, xmax, ymax], outline=color)img_data.save(save_path)def xywhn2xyxy(x, w=640, h=640, padw=0, padh=0):# Convert nx4 boxes from [x, y, w, h] normalized to [x1, y1, x2, y2] where xy1=top-left, xy2=bottom-righty = copy.deepcopy(x)y[0] = w * (x[0] - x[2] / 2) + padw  # top left xy[1] = h * (x[1] - x[3] / 2) + padh  # top left yy[2] = w * (x[0] + x[2] / 2) + padw  # bottom right xy[3] = h * (x[1] + x[3] / 2) + padh  # bottom right yreturn y        def vis_yolo(yolo_dir, save_root):"""_summary_Args:yolo_dir (str): yolo数据集路径save_root (str): 图像保存路径"""yolo_img_dir = Path(yolo_dir) / "images/"yolo_label_dir = Path(yolo_dir) / 'labels/'txt_files = yolo_label_dir.glob("./*.txt")for txt_path in txt_files:with open(txt_path, "r") as f:label_data = f.readlines()name = txt_path.stemimg_path = yolo_img_dir / f"{name}.jpg"if img_path.is_file():img_data = cv2.imread(str(img_path))h0, w0, _ = img_data.shapebboxes = list()for bbox in label_data:bbox = bbox.split(" ")xywh = [float(x) for x in bbox[1:]]xyxy = xywhn2xyxy(xywh, w=w0, h=h0)bboxes.append(xyxy)save_path = os.path.join(save_root, img_path.name)display(str(img_path), bboxes, save_path)if __name__ == "__main__":yolo_root = "yolo"save_root = "vis_yolo"vis_yolo(yolo_root, save_root)

3. 与coco之间的转换

COCO(Common Objects in Context)是一个常用的目标检测、语义分割和图像标注任务的数据集格式。COCO数据集是一个大规模的图像数据集,包含了多个类别的目标物体和对应的标注信息。

COCO数据集的标注信息以JSON格式存储,其中包含了图像的信息、目标物体的类别、边界框的位置、分割掩码等。

coco格式

COCO数据集的每个图像对应一个JSON文件,其中的主要字段包括:

  • “info”: 数据集的相关信息,如版本、作者等。
  • “licenses”: 数据集的许可证信息。
  • “images”: 图像的信息,包括图像ID、文件名、宽度、高度等。
  • “annotations”: 目标物体的标注信息,包括目标ID、类别ID、边界框位置、分割掩码等。
  • “categories”: 目标类别的信息,包括类别ID和类别名称。

具体而言,每个标注信息的格式如下:

{"id": <annotation_id>,"image_id": <image_id>,"category_id": <category_id>,"bbox": [x, y, width, height],"segmentation": <segmentation_data>,"area": <area>,"iscrowd": <iscrowd>
}
  • "id" 表示标注的唯一ID。
  • "image_id" 表示对应图像的ID。
  • "category_id" 表示目标物体所属的类别ID。
  • "bbox" 表示目标物体的边界框位置,由左上角顶点的坐标 (x, y) 和宽度、高度 (width, height) 组成。
  • "segmentation" 表示目标物体的分割掩码,可以是多边形或二进制掩码。
  • "area" 表示目标物体的面积。
  • "iscrowd" 表示目标物体是否是密集分布的群体。

COCO数据集提供了丰富的目标检测和分割任务所需的信息,使得研究者和开发者能够更好地进行算法的训练和评估。

labelme转coco

labelme和coco之间的转换脚本如下:

import os
import json
from tqdm import tqdm
from pathlib import Path
import shutildef read_json(json_path):with open(json_path) as f:json_data = json.load(f)return json_datadef get_categories(cls_path):assert(os.path.exists(cls_path)), f"cannot find classes file"with open(cls_path) as f:data = f.readlines()res = list()name2idx = dict()for idx, cls in enumerate(data):res.append({"id":idx + 1, "name": cls.strip()})name2idx[cls.strip()] = idx + 1return res, name2idxdef get_image(json_data, image_id):image_dict = {}image_dict['height'] = json_data["imageHeight"]image_dict['width'] = json_data["imageWidth"]image_dict['id'] = image_idimage_dict['file_name'] = json_data["imagePath"]return image_dictdef construct_annotation(img_id, ann_id, category_id, bbox, area, iscrowd=0):annotation = {}annotation['id'] = ann_idannotation['image_id'] = img_idannotation['category_id'] = category_idannotation['bbox'] = bboxannotation['area'] = areaannotation['iscrowd'] = iscrowdannotation['segmentation'] = []return annotationdef get_annotation(objects, image_id, annotation_id, name2idx):annotation_list = []for item in objects:points = item["points"]# points = [round(x, 2) for x in points]      # [x1, y1, x2, y2]x1, y1 = points[0]x2, y2 = points[1]box_w = abs(x2 - x1)box_h = abs(y2 - y1)points = [x1, y1, box_w, box_h]tagtype = item["label"]   category_id = name2idx[tagtype]area = box_w * box_h   annotation_list.append(construct_annotation(image_id, annotation_id, category_id, points, area))annotation_id += 1return annotation_list, annotation_iddef save_coco_json(instance, save_path):import iowith io.open(save_path, 'w', encoding="utf-8") as outfile:my_json_str = json.dumps(instance, ensure_ascii=False, indent=1)outfile.write(my_json_str)def construct_coco(labelme_root, coco_img_root, coco_anno_root, cls_path):# 1. 构建COCO格式结构instance = {}instance['info'] = 'spytensor created'instance['license'] = ['license']# 2. 获取类别信息instance['categories'], name2idx =  get_categories(cls_path)images_all = []image_id = 1annotations_all = []annotation_id = 1json_files = Path(labelme_root).glob("./*.json")for json_path in tqdm(json_files):   json_data = read_json(json_path)img_name = json_data["imagePath"]objects = json_data['shapes']if not os.path.exists(os.path.join(labelme_root, img_name)): continueif len(objects)==0 :print(f"no object existed in {img_name}")# continueelse:# 处理标注数据内容annotation_list, annotation_id = get_annotation(objects, image_id, annotation_id, name2idx)annotations_all.extend(annotation_list)img_dict = get_image(json_data, image_id)images_all.append(img_dict)image_id += 1shutil.copyfile(os.path.join(labelme_root, img_name), os.path.join(coco_img_root, img_name))instance['images'] = images_allinstance['annotations'] = annotations_allsave_coco_json(instance, coco_anno_root)if __name__ == "__main__":labelme_root = "labelme"coco_img_root = "coco/train"coco_anno_path = "coco/annotations/train.json"cls_path  = "coco/classes.txt"construct_coco(labelme_root, coco_img_root, coco_anno_path, cls_path)

可视化

coco格式数据可视化需要安装pycocotools库,脚本需要指定coco数据集的图像位置和json位置,以及最后可视化结果保存位置。

from pycocotools.coco import COCO
from PIL import Image, ImageDraw
import osdef display(coco, img_id, img_root, save_root, cat_ids=None):"""基于给定的img_id, 可视化其标注内容"""# 获取images字段内容images = coco.loadImgs(ids=[img_id])[0]# 获取到annotation结构体annotation_id = coco.getAnnIds(imgIds=images['id'], catIds=cat_ids, iscrowd=None)# 加载对应的annotation结构体内容annotations = coco.loadAnns(annotation_id)print(annotations)file_path = os.path.join(img_root, images["file_name"])# print(file_path)img_data = Image.open(file_path).convert("RGB")draw = ImageDraw.Draw(img_data)for anno in annotations:bbox = anno["bbox"]x1, y1, box_w, box_h = bboxx2, y2 = x1 + box_w, y1 + box_hx1, y1, x2, y2 = int(x1), int(y1), int(x2), int(y2)draw.rectangle([x1,y1,x2,y2], outline=(255, 0,0 ))img_data.save(os.path.join(save_root, os.path.basename(images["file_name"])))if __name__ == "__main__":annFile="coco/annotations/train.json"# 初始化标注数据的 COCO api coco=COCO(annFile)# 获取COCO数据集所有的类别IDclass_ids = coco.getCatIds()# 获取catIds对应的所有image_idimgIds = coco.getImgIds(catIds=class_ids )img_ids = imgIdsfor id in img_ids:display(coco, img_id=id, cat_ids=[1], img_root="coco/train", save_root="vis_coco/")

总结

本文中,主要介绍了labelme在目标检测任务中的用法,以及对应的数据格式。重点在于给出了labelme与常见目标检测数据格式yolo和coco之间相互转换的脚本,并提供各自的可视化脚本用于检查转换后格式是否正确。

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

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

相关文章

智能监控平台/视频共享融合系统EasyCVR海康设备国标GB28181接入流程

TSINGSEE青犀视频监控汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防视频监控的能力&…

C# 使用Pipelines处理Socket数据包

写在前面 在上一篇中对Pipelines进行简单的了解&#xff0c;同时也留下了未解的问题&#xff0c;如何将Pipelines类库运用到Socket通讯过程中来解决粘包和分包。链接地址如下&#xff1a; 初识System.IO.Pipelines https://rjcql.blog.csdn.net/article/details/135211047 这…

Hive安装笔记——备赛笔记——2024全国职业院校技能大赛“大数据应用开发”赛项——任务2:离线数据处理

将下发的ds_db01.sql数据库文件放置mysql中 12、编写Scala代码&#xff0c;使用Spark将MySQL的ds_db01库中表user_info的全量数据抽取到Hive的ods库中表user_info。字段名称、类型不变&#xff0c;同时添加静态分区&#xff0c;分区字段为etl_date&#xff0c;类型为String&am…

前端开发之通过vue-office组件实现文件预览

前端开发之通过vue-office组件实现文件预览 前言效果图docx文件xlsx文件pdf文件 vue中简单案例1、安装组件2、vue中代码 前言 在实现文件预览的时候我们可以通过vue-office组件来实现文件的预览效果 效果图 docx文件 xlsx文件 pdf文件 vue中简单案例 1、安装组件 整体安装…

RabbitMQ入门指南(九):消费者可靠性

专栏导航 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、消费者确认机制 二、失败重试机制 三、失败处理策略 四、业务幂等性 1.通过唯一标识符保证操作的幂等性 2.通过业务判断保证操作的幂等性 总结 前言 RabbitMQ是一个高效、可靠的开源消息队列系…

词表示:语言与计算的桥梁

目录 前言1 什么是词表示2 独热表示3 上下文表示4 分布式表示结语 前言 在自然语言处理领域&#xff0c;词语的表示是一个基本挑战。将词语转换为计算机可以理解的符号&#xff0c;衡量词语之间的相似度&#xff0c;捕捉它们之间复杂的关系&#xff0c;是使机器能够理解和处理…

Bluetooth Mesh 入门学习干货,参考Nordic资料(更新中)

蓝牙网状网络&#xff08;Bluetooth mesh&#xff09;概念 概述 蓝牙Mesh Profile | Bluetooth Technology Website规范&#xff08;Mesh v1.1 后改名Mesh ProtocolMesh Protocol | Bluetooth Technology WebsiteMesh Protocol&#xff09;是由蓝牙技术联盟(Bluetooth SIG)开…

EasyExcel实现动态表头(注解实现)

要实现上述动态头&#xff0c;按每日统计&#xff0c;每月统计&#xff0c;每年统计。而时间是一直变化&#xff0c;所以我们需要表头也一直动态生成。 首先&#xff0c;我们需要定义所需要实体类 public class CountDayData {ExcelProperty(value "业务员姓名")p…

css 设置字体渐变色和阴影

一、需求 我们平时写样式的时候可能遇到需要将字体设置成渐变色&#xff0c;这样能使界面整体美化提升&#xff0c;那么css怎么去实现这个功能呢&#xff1f;下面我介绍一种常用的方法&#xff0c;欢迎大家补充 二、渐变实现 先看效果图&#xff1a; 直接上代码&#xff1a; /…

Seem环境安装

创建虚拟环境 conda create -n seem python3.8 conda activate seem 安装相关依赖&#xff1a;&#xff08;不按照的话会报错&#xff09; sudo apt-get install openmpi-bin libopenmpi-devconda install gcc_linux-64pip install mpi4py 导入环境 export PYTHONPATH$(pwd…

开发效率之把握需求、减少返工

前言 当年初入软件开发行业的我&#xff0c;拿到需求就莽&#xff0c;要设计没设计&#xff0c;要分析没分析&#xff0c;结果就是没理清楚需求&#xff0c;致使频频返工。 需求没理解对&#xff0c;做得再多再好也白搭。 估算需求把握程度 假如每个IF分支的“是”加一分&…

2024 年全球顶级的 3 款 桌面 PDF 转换工具

桌面 PDF 转换器工具是一种软件应用程序&#xff0c;使用户能够将 PDF 文件与不同的文件格式相互转换。奇客PDF转换、Nitro Pro 和 Foxit PhantomPDF 是市场上最好的桌面 PDF 转换工具。 在选择最好的 PDF 转换器软件时&#xff0c;需要考虑的一个重要因素是它与其他软件的集成…

nvm 的安装及使用 (Node版本管理器)

目录 1、nvm 介绍 2、nvm安装 3、nvm 使用 4、node官网可以查看node和npm对应版本 5、nvm安装指定版本node 6、安装cli脚手架 1、nvm 介绍 NVM 全称 node.js version management &#xff0c;专门针对 node 版本进行管理的工具&#xff0c;通过它可以安装和切换不同版本的…

数据链路层解读

基本介绍 概述 数据链路层使用的信道主要有两种类型 点对点信道。使用一对一的点对点通信方式的信道。广播信道。使用一对多的广播通信方式的信道。由于广播信道上连接的主机很多&#xff0c;必须使用专用的共享信道协议来协调这些主机的数据发送&#xff0c;因此通信过程比较…

【Windows】共享文件夹拍照还原防火墙设置(入站,出站设置)---图文并茂详细讲解

目录 一 共享文件夹(两种形式) 1.1 普通共享与高级共享区别 1.2 使用 二 拍照还原 2.1 是什么 2.2 使用 三 防火墙设置&#xff08;入栈&#xff0c;出站设置&#xff09; 3.1 引入 3.2 入站出站设置 3.2.1入站出站含义 3.3入站设置 3.4安装jdk 3.5使用tomcat进行访…

sql_lab之sqli中的堆叠型注入(less-38)

堆叠注入&#xff08;less-38&#xff09; 1.判断注入类型 http://127.0.0.3/less-38/?id1 and 12 -- s 没有回显 http://127.0.0.3/less-38/?id1 and 11 -- s 有回显 则说明是单字节’注入 2.查询字段数 http://127.0.0.3/less-38/?id1 order by 4 -- s 报错 http:/…

智能优化算法应用:基于人工兔算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于人工兔算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于人工兔算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.人工兔算法4.实验参数设定5.算法结果6.参考文…

取证工具volatility插件版学习记录

更新时间&#xff1a;2023年12月18日11:48:29 1. 背景描述 在以前学习过volatility的基础功能&#xff0c;主要是使用volatility独立版进行学习的&#xff0c;前几天遇到一个ctf赛事&#xff0c;需要用到的是volatility的mimikatz模块&#xff0c;因为以前没使用过那个模块&…

【Filament】立方体贴图(6张图)

1 前言 本文通过一个立方体贴图的例子&#xff0c;讲解三维纹理贴图&#xff08;子网格贴图&#xff09;的应用&#xff0c;案例中使用 6 张不同的图片给立方体贴图&#xff0c;图片如下。 读者如果对 Filament 不太熟悉&#xff0c;请回顾以下内容。 Filament环境搭建绘制三角…

HTML制作暴雨特效

🎀效果展示 🎀代码展示 <body> <!-- partial:index.partial.html --> <canvas id="canvas-club">