YOLO航拍车辆和行人识别

news2024/9/23 7:22:15

YOLO航拍车辆和行人识别
图片数量9695,标注为xml和txt格式;
class:car,pedestrian,truck,bus



用于yolo,Python,目标检测,机器学习,人工智能,深度学习,车辆识别,公交车识别,货车识别,行人识别,无人机航拍识别

 

数据集名称

YOLO航拍车辆和行人识别数据集

数据集描述

该数据集是一个专门用于训练和评估基于YOLO(You Only Look Once)架构的目标检测模型的数据集,旨在帮助研究人员和开发者在无人机航拍图像中识别车辆(包括轿车、卡车、公交车)和行人。数据集包含9695张高质量的航拍图片,并提供了详细的边界框标注信息,支持直接用于训练目标检测模型。通过高质量的数据和详细的标注信息,该数据集为开发高效且准确的目标检测系统提供了坚实的基础。

数据规模

  • 总样本数量:9695张图片
  • 标注格式
    • Pascal VOC XML格式
    • YOLO txt格式

图像特性

  • 多样化场景:覆盖了多种城市和乡村环境下的航拍图像,包括不同的天气条件、光照条件和背景。
  • 高质量手工标注:每张图像都有详细的边界框标注,支持直接用于训练目标检测模型。
  • 多类别支持:主要关注四类目标:car(轿车)、pedestrian(行人)、truck(卡车)、bus(公交车)。
  • 无需预处理:数据集已经过处理,可以直接用于训练,无需额外的数据预处理步骤。

应用场景

  • 智能监控:自动检测航拍图像中的车辆和行人,辅助管理人员进行交通监控和管理。
  • 无人机应用:集成到无人机系统中,实现对地面目标的实时检测和跟踪。
  • 科研分析:用于研究目标检测算法在特定应用场景中的表现,特别是在复杂背景和高视角条件下的鲁棒性。
  • 教育与培训:可用于安全相关的教育和培训项目,帮助学生和从业人员更好地理解航拍图像中的目标检测技术。
  • 自动化管理:集成到智能交通管理系统中,实现对道路状况的自动化监测和管理。

数据集结构

典型的数据集目录结构如下:

 
1aerial_vehicle_pedestrian_dataset/
2├── images/
3│   ├── img_00001.jpg
4│   ├── img_00002.jpg
5│   └── ...
6├── annotations/
7│   ├── img_00001.xml  # Pascal VOC XML格式
8│   ├── img_00002.xml
9│   └── ...
10├── labels/  # YOLO txt格式
11│   ├── img_00001.txt
12│   ├── img_00002.txt
13│   └── ...
14├── scripts/
15│   ├── convert_voc_to_yolo.py
16│   ├── train_yolo.py
17│   ├── evaluate_yolo.py
18│   ├── visualize_annotations.py
19│   └── data_augmentation.py
20├── README.txt  # 数据说明文件

数据说明

  • 检测目标:以Pascal VOC XML格式和YOLO txt格式进行标注。
  • 数据集内容
    • 总共9695张图片,每张图片都带有相应的XML和txt标注文件。
  • 标签类型
    • 边界框 (Bounding Box)
  • 数据增广:数据集未做数据增广,用户可以根据需要自行进行数据增广。
  • 无需预处理:数据集已经过处理,可以直接用于训练,无需额外的数据预处理步骤。

示例代码

以下是一些常用脚本的示例代码,包括将VOC格式转换为YOLO格式、训练YOLO模型、评估模型性能、可视化标注以及数据增强。

脚本1: 将VOC格式转换为YOLO格式
1# convert_voc_to_yolo.py
2import os
3import xml.etree.ElementTree as ET
4
5def convert_voc_to_yolo(xml_file, image_size):
6    tree = ET.parse(xml_file)
7    root = tree.getroot()
8    yolo_lines = []
9
10    for obj in root.findall('object'):
11        name = obj.find('name').text
12        bbox = obj.find('bndbox')
13        xmin = int(bbox.find('xmin').text)
14        ymin = int(bbox.find('ymin').text)
15        xmax = int(bbox.find('xmax').text)
16        ymax = int(bbox.find('ymax').text)
17
18        x_center = (xmin + xmax) / 2.0 / image_size[0]
19        y_center = (ymin + ymax) / 2.0 / image_size[1]
20        width = (xmax - xmin) / image_size[0]
21        height = (ymax - ymin) / image_size[1]
22
23        class_id = 0 if name == 'car' else 1 if name == 'pedestrian' else 2 if name == 'truck' else 3  # 假设只有四个类别
24        yolo_line = f"{class_id} {x_center} {y_center} {width} {height}\n"
25        yolo_lines.append(yolo_line)
26
27    return yolo_lines
28
29def main():
30    voc_dir = 'path/to/annotations'
31    yolo_dir = 'path/to/labels'
32    image_dir = 'path/to/images'
33
34    if not os.path.exists(yolo_dir):
35        os.makedirs(yolo_dir)
36
37    for xml_file in os.listdir(voc_dir):
38        if xml_file.endswith('.xml'):
39            image_path = os.path.join(image_dir, xml_file.replace('.xml', '.jpg'))
40            image = Image.open(image_path)
41            image_size = image.size
42
43            yolo_lines = convert_voc_to_yolo(os.path.join(voc_dir, xml_file), image_size)
44            with open(os.path.join(yolo_dir, xml_file.replace('.xml', '.txt')), 'w') as f:
45                f.writelines(yolo_lines)
46
47if __name__ == "__main__":
48    main()
脚本2: 训练YOLO模型
1# train_yolo.py
2import os
3import torch
4from yolov5 import train
5
6def main():
7    data_yaml = 'path/to/data.yaml'  # 包含数据集路径和类别的配置文件
8    model_yaml = 'path/to/model.yaml'  # 模型配置文件
9    weights = 'path/to/weights.pt'  # 预训练权重(可选)
10    epochs = 100
11    batch_size = 8
12    img_size = 640
13
14    train.run(
15        data=data_yaml,
16        cfg=model_yaml,
17        weights=weights,
18        epochs=epochs,
19        batch_size=batch_size,
20        imgsz=img_size
21    )
22
23if __name__ == "__main__":
24    main()
脚本3: 评估YOLO模型
 
1# evaluate_yolo.py
2import os
3import torch
4from yolov5 import val
5
6def main():
7    data_yaml = 'path/to/data.yaml'  # 包含数据集路径和类别的配置文件
8    weights = 'path/to/best.pt'  # 训练好的模型权重
9    img_size = 640
10
11    val.run(
12        data=data_yaml,
13        weights=weights,
14        imgsz=img_size
15    )
16
17if __name__ == "__main__":
18    main()
脚本4: 可视化标注
1# visualize_annotations.py
2import os
3import cv2
4import numpy as np
5from PIL import Image
6import xml.etree.ElementTree as ET
7
8def load_image_and_boxes(image_path, annotation_path):
9    # 读取图像
10    image = Image.open(image_path).convert('RGB')
11    
12    # 解析Pascal VOC格式的XML标注文件
13    tree = ET.parse(annotation_path)
14    root = tree.getroot()
15    boxes = []
16    for obj in root.findall('object'):
17        class_name = obj.find('name').text
18        bbox = obj.find('bndbox')
19        xmin = int(bbox.find('xmin').text)
20        ymin = int(bbox.find('ymin').text)
21        xmax = int(bbox.find('xmax').text)
22        ymax = int(bbox.find('ymax').text)
23        boxes.append([class_name, xmin, ymin, xmax, ymax])
24    
25    return image, boxes
26
27def show_image_with_boxes(image, boxes):
28    img = np.array(image)
29    for box in boxes:
30        class_name, xmin, ymin, xmax, ymax = box
31        cv2.rectangle(img, (xmin, ymin), (xmax, ymax), (0, 255, 0), 2)
32        label = f'{class_name}'
33        cv2.putText(img, label, (xmin, ymin - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
34    
35    cv2.imshow('Image with Boxes', img)
36    cv2.waitKey(0)
37    cv2.destroyAllWindows()
38
39def main():
40    images_dir = 'path/to/images'
41    annotations_dir = 'path/to/annotations'
42    
43    # 获取图像列表
44    image_files = [f for f in os.listdir(images_dir) if f.endswith('.jpg')]
45    
46    # 随机选择一张图像
47    selected_image = np.random.choice(image_files)
48    image_path = os.path.join(images_dir, selected_image)
49    annotation_path = os.path.join(annotations_dir, selected_image.replace('.jpg', '.xml'))
50    
51    # 加载图像和边界框
52    image, boxes = load_image_and_boxes(image_path, annotation_path)
53    
54    # 展示带有边界框的图像
55    show_image_with_boxes(image, boxes)
56
57if __name__ == "__main__":
58    main()
脚本5: 数据增强
1# data_augmentation.py
2import os
3import cv2
4import numpy as np
5import albumentations as A
6from PIL import Image
7import xml.etree.ElementTree as ET
8
9def load_image_and_boxes(image_path, annotation_path):
10    # 读取图像
11    image = Image.open(image_path).convert('RGB')
12    image = np.array(image)
13    
14    # 解析Pascal VOC格式的XML标注文件
15    tree = ET.parse(annotation_path)
16    root = tree.getroot()
17    boxes = []
18    for obj in root.findall('object'):
19        class_name = obj.find('name').text
20        bbox = obj.find('bndbox')
21        xmin = int(bbox.find('xmin').text)
22        ymin = int(bbox.find('ymin').text)
23        xmax = int(bbox.find('xmax').text)
24        ymax = int(bbox.find('ymax').text)
25        boxes.append([xmin, ymin, xmax, ymax, class_name])
26    
27    return image, boxes
28
29def save_augmented_data(augmented_image, augmented_boxes, output_image_path, output_annotation_path):
30    # 保存增强后的图像
31    augmented_image = Image.fromarray(augmented_image)
32    augmented_image.save(output_image_path)
33    
34    # 保存增强后的标注
35    tree = ET.parse(output_annotation_path)
36    root = tree.getroot()
37    for obj, new_box in zip(root.findall('object'), augmented_boxes):
38        bbox = obj.find('bndbox')
39        bbox.find('xmin').text = str(new_box[0])
40        bbox.find('ymin').text = str(new_box[1])
41        bbox.find('xmax').text = str(new_box[2])
42        bbox.find('ymax').text = str(new_box[3])
43    
44    tree.write(output_annotation_path)
45
46def augment_data(image, boxes):
47    transform = A.Compose([
48        A.RandomRotate90(p=0.5),
49        A.HorizontalFlip(p=0.5),
50        A.VerticalFlip(p=0.5),
51        A.RandomBrightnessContrast(p=0.2),
52        A.HueSaturationValue(p=0.2)
53    ], bbox_params=A.BboxParams(format='pascal_voc', label_fields=['category_ids']))
54
55    category_ids = [box[-1] for box in boxes]
56    bboxes = [box[:-1] for box in boxes]
57    
58    transformed = transform(image=image, bboxes=bboxes, category_ids=category_ids)
59    transformed_image = transformed['image']
60    transformed_bboxes = transformed['bboxes']
61    
62    return transformed_image, transformed_bboxes
63
64def main():
65    images_dir = 'path/to/images'
66    annotations_dir = 'path/to/annotations'
67    output_images_dir = 'path/to/augmented_images'
68    output_annotations_dir = 'path/to/augmented_annotations'
69    
70    if not os.path.exists(output_images_dir):
71        os.makedirs(output_images_dir)
72    
73    if not os.path.exists(output_annotations_dir):
74        os.makedirs(output_annotations_dir)
75    
76    # 获取图像列表
77    image_files = [f for f in os.listdir(images_dir) if f.endswith('.jpg')]
78    
79    for image_file in image_files:
80        image_path = os.path.join(images_dir, image_file)
81        annotation_path = os.path.join(annotations_dir, image_file.replace('.jpg', '.xml'))
82        
83        # 加载图像和边界框
84        image, boxes = load_image_and_boxes(image_path, annotation_path)
85        
86        # 增强数据
87        augmented_image, augmented_boxes = augment_data(image, boxes)
88        
89        # 保存增强后的数据
90        output_image_path = os.path.join(output_images_dir, image_file)
91        output_annotation_path = os.path.join(output_annotations_dir, image_file.replace('.jpg', '.xml'))
92        save_augmented_data(augmented_image, augmented_boxes, output_image_path, output_annotation_path)
93
94if __name__ == "__main__":
95    main()

项目介绍

项目名称

基于YOLO的航拍车辆和行人识别系统

项目描述

该项目旨在开发一个基于YOLO架构的航拍图像中的车辆和行人识别系统。通过使用上述数据集,我们将训练一个高效的深度学习模型,能够在无人机拍摄的高分辨率图像中实时检测并分类轿车、行人、卡车和公交车。项目的主要目标是提高交通管理和城市规划的效率,同时为无人机应用提供强大的视觉感知能力。

项目目标

  • 实时检测:实现对航拍图像中车辆和行人的实时检测。
  • 高精度分类:能够准确地区分不同类型的车辆(轿车、卡车、公交车)和行人。
  • 鲁棒性:在不同天气条件、光照条件和背景下保持良好的检测性能。
  • 易用性:提供易于部署和使用的接口,方便集成到现有的无人机系统中。

项目结构

1aerial_vehicle_pedestrian_detection_project/
2├── data/
3│   ├── aerial_vehicle_pedestrian_dataset/
4│   │   ├── images/
5│   │   ├── annotations/
6│   │   ├── labels/
7│   │   ├── scripts/
8│   │   └── README.txt
9├── models/
10│   ├── yolov5s.pt  # 预训练模型
11│   ├── best.pt  # 最佳训练模型
12├── config/
13│   ├── data.yaml  # 数据集配置文件
14│   ├── model.yaml  # 模型配置文件
15├── scripts/
16│   ├── convert_voc_to_yolo.py
17│   ├── train_yolo.py
18│   ├── evaluate_yolo.py
19│   ├── visualize_annotations.py
20│   ├── data_augmentation.py
21│   ├── inference.py  # 推理脚本
22├── notebooks/
23│   ├── data_exploration.ipynb  # 数据探索笔记本
24│   ├── model_training.ipynb  # 模型训练笔记本
25│   ├── model_evaluation.ipynb  # 模型评估笔记本
26├── requirements.txt  # 依赖库
27└── README.md  # 项目说明文件

项目流程

  1. 数据准备

    • 下载并解压数据集。
    • 使用convert_voc_to_yolo.py脚本将VOC格式的标注转换为YOLO格式。
  2. 数据探索

    • 使用data_exploration.ipynb笔记本探索数据集,了解数据分布和质量。
  3. 数据增强

    • 使用data_augmentation.py脚本对数据进行增强,增加数据多样性。
  4. 模型训练

    • 使用train_yolo.py脚本训练YOLO模型。
    • 根据需要调整超参数和模型配置。
  5. 模型评估

    • 使用evaluate_yolo.py脚本评估模型性能。
    • 生成混淆矩阵和分类报告。
  6. 推理和应用

    • 使用inference.py脚本进行实时检测和分类。
    • 将模型集成到无人机系统或其他应用中。
  7. 结果可视化

    • 使用visualize_annotations.py脚本可视化检测结果。

改进方向

如果您已经使用上述方法对该数据集进行了训练,并且认为还有改进空间,以下是一些可能的改进方向:

  1. 数据增强

    • 进一步增加数据增强策略,例如旋转、翻转、缩放、颜色抖动等,以提高模型的泛化能力。
    • 使用混合增强技术,如MixUp、CutMix等,以增加数据多样性。
  2. 模型优化

    • 调整模型超参数,例如学习率、批量大小、优化器等,以找到最佳配置。
    • 尝试使用不同的骨干网络(Backbone),例如EfficientNet、ResNet等,以提高特征提取能力。
    • 引入注意力机制,如SENet、CBAM等,以增强模型对关键区域的关注。
  3. 损失函数

    • 尝试使用不同的损失函数,例如Focal Loss、IoU Loss等,以改善模型的收敛性能。
    • 结合多种损失函数,例如分类损失和回归损失的组合,以平衡不同类型的任务。
  4. 后处理

    • 使用非极大值抑制(NMS)的改进版本,如Soft-NMS、DIoU-NMS等,以提高检测结果的质量。
    • 引入边界框回归的改进方法,如GIoU、CIoU等,以提高定位精度。
  5. 迁移学习

    • 使用预训练模型进行微调,利用大规模数据集(如COCO、ImageNet)上的预训练权重,加快收敛速度并提高性能。
  6. 集成学习

    • 使用多个模型进行集成学习,通过投票或加权平均的方式提高最终的检测效果。

通过上述方法,可以进一步提升模型在航拍车辆和行人识别任务上的性能。

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

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

相关文章

软件测试分类篇(下)

目录 一、按照测试阶段分类 1. 单元测试 2. 集成测试 3. 系统测试 3.1 冒烟测试 3.2 回归测试 4. 验收测试 二、按照是否手工测试分类 1. 手工测试 2. 自动化测试 3. 手工测试和自动化测试的优缺点 三、按照实施组织分类 1. α测试(Alpha Testing) 2. β测试(Beta…

图像放大效果示例【JavaScript】

实现效果&#xff1a; 当鼠标悬停在小图&#xff08;缩略图&#xff09;上时&#xff0c;大图&#xff08;预览图&#xff09;会随之更新为相应的小图&#xff0c;并高亮当前悬浮的小图的父元素。 代码&#xff1a; 1. HTML部分 <!DOCTYPE html> <html lang"z…

Nginx简介;Nginx安装

一&#xff0c;Nginx简介 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器&#xff0c;在BSD-like 协议下发行。是一个高性能的HTTP和反向代理web服务器 &#xff0c;同时也提供了IMAP/POP3/SMTP服务。 其特点是占有内存少…

OpenCV特征检测(8)检测图像中圆形的函数HoughCircles()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在灰度图像中使用霍夫变换查找圆形。 该函数使用霍夫变换的一种修改版本在灰度图像中查找圆形。 例子&#xff1a; #include <opencv2/imgp…

【解密 Kotlin 扩展函数】扩展函数的创建(十六)

导读大纲 1.1 为第三方的类添加方法: 扩展函数 1.1 为第三方的类添加方法: 扩展函数 Kotlin 的主题之一是与现有代码的平滑集成 即使是纯 Kotlin 项目,也是构建在 Java 库之上的 如 JDK、Android 框架和其他第三方框架 而当你将 Kotlin 集成到 Java 项目中时 你还要处理尚未或不…

Ubuntu清理内存导致的一系列错误及解决方法

文章目录 火狐浏览器和pycharm消失打不开 安不上 卸不掉后记 火狐浏览器和pycharm消失 打不开 安不上 卸不掉 清理内存后&#xff0c;火狐和pycharm的图标都消失了&#xff0c;在终端输入Firefox显示无法打开 应当先snap install firefox&#xff0c;然而snap install firefo…

【排序算法】插入排序_直接插入排序、希尔排序

文章目录 直接插入排序直接插入排序的基本思想直接插入排序的过程插入排序算法的C代码举例分析插入排序的复杂度分析插入排序的优点 希尔排序希尔排序&#xff08;Shell Sort&#xff09;详解希尔排序的步骤&#xff1a;希尔排序的过程示例&#xff1a;希尔排序的C语言实现举例…

啥?Bing搜索古早BUG至今未改?

首先&#xff0c;大家先看下面的一个数学公式。 Γ ( z ) ∫ 0 ∞ t z − 1 e − t d t . \Gamma(z) \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)∫0∞​tz−1e−tdt. 看不懂&#xff1f;没关系&#xff0c;因为我也看不懂 这不是谈论的重点。 当你把鼠标光标移到公式的最开头&…

netflix是什么样的企业文化

netflix是什么样的企业文化 Netflix的企业文化以其“自由与责任”而闻名&#xff0c;这种文化理念在业界被广泛誉为管理的“黄金法则”。《奈飞文化手册》自2009年面世以来&#xff0c;便迅速成为全球企业管理的典范&#xff0c;吸引了超过1500万次的在线阅读与下载。Netflix的…

【C++篇】引领C++模板初体验:泛型编程的力量与妙用

文章目录 C模板编程前言第一章: 初始模板与函数模版1.1 什么是泛型编程&#xff1f;1.1.1 为什么要有泛型编程&#xff1f;1.1.1 泛型编程的优势 1.2 函数模板的基础1.2.1 什么是函数模板&#xff1f;1.2.2 函数模板的定义格式1.2.3 示例&#xff1a;通用的交换函数输出示例&am…

【网络】高级IO——Reactor版TCP服务器

目录 1.什么是Reactor 1.1.餐厅里的Reactor模式 2.Reactor的由来 2.1.单 Reactor 单进程 / 线程 2.2.单 Reactor 多线程 / 多进程 2.3.多 Reactor 多进程 / 线程 3.实现单 Reactor 单进程版本的TCP服务器 3.1.Connection类 3.2.TcpServer类 3.3.Connection的真正用处 …

深蓝学院-- 量产自动驾驶中的规划控制算法 小鹏

文章目录 0. 前言1.发展现状2.行车功能中难点问题及解决思路问题1&#xff1a;车道居中辅助&#xff0c;画龙&#xff0c;蛇行问题。问题2&#xff1a;外界环境扰动以及传感器信息缺失下的横向控制难点问题3&#xff1a;大坡度平稳停车 3. 泊车功能中难点问题及解决思路问题1&a…

Spring AOP - 配置文件方式实现

目录 AOP基础概念 示例1&#xff1a;模拟在com.text包及子包项下所有类名称以ServiceImpl结尾的类的所有方法执行前、执行后、执行正常后返回值、执行过程中出异常的情况 示例2&#xff1a;统计com.text包及子包项下所有类名称以DaoImpl结尾的类的所有方法执行时长情况 AOP基…

汽车总线之---- CAN FD总线

CAN FD 最高可支持8M/s的通信速率&#xff0c;从传统CAN到CAN FD的转换是很容易实施和推广的。 CAN FD报文的帧&#xff1a;标准帧&#xff0c;扩展帧 CAN FD 标准帧结构 CAN FD 报文的标准帧与CAN 报文的标准帧的区别 CAN FD 报文的标准帧与CAN FD报文的扩展帧的区别&…

lsof可以查看当前系统中正在被使用的文件,包括动态库

lsof的英文是 list open files lsof打印结果的最后一列是Name&#xff0c;表示正在被使用或打开的文件名或动态库名 lsof直接回车&#xff0c;会显示很多&#xff0c;可以配合more命令查看 一个文件或动态库可能被多个进程打开&#xff0c;lsof会显示多行 lsof | more -1…

uniapp小程序持续获取用户位置信息,后台位置获取

做一个小程序持续获取用户位置信息的功能&#xff0c;即使小程序切换到后台也能继续获取&#xff0c;getLocation这个api只有小程序在前台才能获取位置&#xff0c;所以不用这个 先申请一个腾讯地图key 在uniapp项目配置源码视图里加上这个代码 先获取权限&#xff0c;再开启…

[项目:微服务即时通讯系统客户端(基于C++QT)]三,左侧界面搭建

三&#xff0c;左侧界面搭建 一&#xff0c;导入 先把MainWidget类做成“单例类” 采用的是单例模式&#xff0c;让某一个类&#xff0c;在指定进程中只有唯一的实例 先看一下MainWidget的框架 QWidget//这部分是头文件保护宏&#xff0c;确保该头文件只被包含一次&#x…

240922-chromadb的基本使用

A. 背景介绍 ChromaDB 是一个较新的开源向量数据库&#xff0c;专为高效的嵌入存储和检索而设计。与其他向量数据库相比&#xff0c;ChromaDB 更加专注于轻量化、简单性和与机器学习模型的无缝集成。它的核心目标是帮助开发者轻松管理和使用高维嵌入向量&#xff0c;特别是与生…

【软件工程】数据流图和数据字典

一、数据流图 3.符号 分析结果 二、数据字典 例题 选择题

使用build_chain.sh离线搭建匹配的区块链,并通过命令配置各群组节点的MySQL数据库

【任务】 登陆Linux服务器&#xff0c;以MySQL分布式存储方式安装并部署如图所示的三群组、四机构、 七节点的星形组网拓扑区块链系统。其中&#xff0c;三群组名称分别为group1、group2和group3&#xff0c; 四个机构名称为agencyA、agencyB、agencyC、agencyD。p2p_port、cha…