当前位置: 首页 > news >正文

ChatGPT结合知识图谱构建医疗问答应用 (一) - 构建知识图谱

一、ChatGPT结合知识图谱

在本专栏的前面文章中构建 ChatGPT 本地知识库问答应用,都是基于词向量检索 Embedding 嵌入的方式实现的,在传统的问答领域中,一般知识源采用知识图谱来进行构建,但基于知识图谱的问答对于自然语言的处理却需要耗费大量的人力和物力,而 ChatGPT 本身就拥有强大的自然语言处理能力,如果将ChatGPT和知识图谱相结合岂不是更加强大,本文和下篇文章探索将 ChatGPT结合知识图谱,构建一个基于医疗问答场景的应用。

什么是知识图谱:

知识图谱是一种用于表示和组织结构化知识的图形化模型。它是一种利用图论和语义网络的技术,旨在捕捉信息之间的关联性和语义含义。在问答领域,知识图谱发挥着重要作用。

首先,知识图谱以实体和关系的形式存储知识。实体代表现实世界中的具体事物,例如人、地点、事件等,而关系则描述这些实体之间的联系,例如居住在、发生在等。通过将实体和关系连接为节点和边,知识图谱能够形成一个复杂的网络,反映出知识之间的复杂关系。

其次,知识图谱通过为每个实体和关系添加语义标签,使得计算机能够理解和推理这些知识。这意味着知识图谱能够帮助机器理解实体之间的语义关系,从而回答用户提出的问题。例如,当用户询问“谁是美国第一位总统?”时,知识图谱可以识别到实体“美国”和“总统”,并根据关系“第一位”来回答这个问题。

知识图谱采用经典的 neo4j 图数据来进行构建,在实验前请安装好 neo4j 环境:

在这里插入图片描述

二、医疗数据集

医疗数据集,采用 github刘焕勇老师 分享的数据集,下载地址:

https://github.com/wangle1218/QASystemOnMedicalKG/blob/master/data/medical.json

数据为 JSON 格式,示例如下:

{"_id":{"$oid":"5bb578b6831b973a137e3ee6"},"name":"肺泡蛋白质沉积症","desc":"肺泡蛋白质沉积症(简称PAP),又称Rosen-Castle-man-Liebow综合征,是一种罕见疾病。该病以肺泡和细支气管腔内充满PAS染色阳性,来自肺的富磷脂蛋白质物质为其特征,好发于青中年,男性发病约3倍于女性。","category":["疾病百科","内科","呼吸内科"],"prevent":"1、避免感染分支杆菌病,卡氏肺囊肿肺炎,巨细胞病毒等。\n2、注意锻炼身体,提高免疫力。","cause":"病因未明,推测与几方面因素有关:如大量粉尘吸入(铝,二氧化硅等),机体免疫功能下降(尤其婴幼儿),遗传因素,酗酒,微生物感染等,而对于感染,有时很难确认是原发致病因素还是继发于肺泡蛋白沉着症,例如巨细胞病毒,卡氏肺孢子虫,组织胞浆菌感染等均发现有肺泡内高蛋白沉着。\n虽然启动因素尚不明确,但基本上同意发病过程为脂质代谢障碍所致,即由于机体内,外因素作用引起肺泡表面活性物质的代谢异常,到目前为止,研究较多的有肺泡巨噬细胞活力,动物实验证明巨噬细胞吞噬粉尘后其活力明显下降,而病员灌洗液中的巨噬细胞内颗粒可使正常细胞活力下降,经支气管肺泡灌洗治疗后,其肺泡巨噬细胞活力可上升,而研究未发现Ⅱ型细胞生成蛋白增加,全身脂代谢也无异常,因此目前一般认为本病与清除能力下降有关。","symptom":["紫绀","胸痛","呼吸困难","乏力","毓卓"],"yibao_status":"否","get_prob":"0.00002%","get_way":"无传染性","acompany":["多重肺部感染"],"cure_department":["内科","呼吸内科"],"cure_way":["支气管肺泡灌洗"],"cure_lasttime":"约3个月","cured_prob":"约40%","cost_money":"根据不同医院,收费标准不一致,省市三甲医院约( 8000——15000 元)","check":["胸部CT检查","肺活检","支气管镜检查"],"recommand_drug":[],"drug_detail":[]
}

其中数据集中常用的字段解释:

字段说明
name疾病名称
desc疾病简介
category分类
prevent预防措施
cause疾病病因
symptom疾病症状
yibao_status是否支持医保
get_prob发病率
get_way传染性
acompany并发症
cure_department医疗科目
cure_way治疗方式
cure_lasttime治疗周期
cured_prob治愈概率
cost_money大概花费
check诊断检查项目
recommand_drug建议用药
drug_detail药物详细信息
easy_get疾病易感人群
not_eat不适宜吃的食物
recommand_eat建议吃的食物
common_drug一般用药

三、知识图谱结构规划

由于数据集主要是围绕病症来衍生的,因此除了疾病的属性会多些其余均是为建立关系而创建。

3.1 实体规划

疾病实体(disease)

字段说明
name疾病名称
desc疾病简介
prevent预防措施
cause疾病病因
get_prob发病率
get_way传染性
cure_lasttime治疗周期
cured_prob治愈概率
cost_money大概花费

科室实体(department)

字段说明
name科室名称

疾病症状实体 (symptom)

字段说明
name疾病症状

治疗方式实体 (cureWay)

字段说明
name治疗方式

检查项目实体 (check)

字段说明
name检查项目

用药药物实体 (drug)

字段说明
name药物名称

易感染人群实体 (crowd)

字段说明
name感染人群

食物实体 (food)

字段说明
name食物

3.2 关系规划

开始实体关系结束实体
疾病(disease)疾病科室关系 (diseaseDepartmentRelations)科室实体(department)
疾病(disease)疾病症状关系 (diseaseSymptomRelation)疾病症状实体 (symptom)
疾病(disease)疾病治疗关系 (diseaseCureWayRelation)治疗方式实体 (cureWay)
疾病(disease)疾病检查项目关系 (diseaseCheckRelation)检查项目实体 (check)
疾病(disease)疾病用药关系 (diseaseDrugRelation)药物实体 (drug)
疾病(disease)疾病易感染人群关系 (diseaseCrowdRelation)易感染人群实体 (crowd)
疾病(disease)疾病宜吃食物关系 (diseaseSuitableFoodRelation)食物实体 (food)
疾病(disease)疾病忌吃食物关系 (diseaseTabooFoodRelation)食物实体 (food)
疾病(disease)疾病并发症关系 (diseaseDiseaseRelation)疾病(disease)

四、知识图谱构建

在里采用 Python 语言构建,需要安装 py2neo 库:

pip install py2neo -i https://pypi.tuna.tsinghua.edu.cn/simple
from py2neo import Graph
import os
from tqdm import tqdm
import jsonclass CreateKG():def __init__(self, kg_host, kg_port, kg_user, kg_password, data_path):self.graph = Graph(host=kg_host,http_port=kg_port,user=kg_user,password=kg_password)if not data_path or data_path == '':raise Exception("数据集地址为空")if not os.path.exists(data_path):raise Exception("数据集不存在")self.data_path = data_pathdef saveEntity(self, label, data):print("\n写入实体:", label)for item in tqdm(data, ncols=80):try:property = []for key, value in item.items():value = value.replace("'", "")property.append(key + ":" + "'" + value + "'")if len(property) == 0:continuecql = "MERGE(n:" + label + "{" + ",".join(property) + "})"self.graph.run(cql)except Exception as e:passdef saveRelation(self, s_label, e_label, label, data):print("\n写入关系:", label)for item in tqdm(data, ncols=80):try:s_name = item["s_name"]e_name = item["e_name"]cql = "MATCH(p:" + s_label + "),(q:" + e_label + ") WHERE p.name='" + s_name + "' AND q.name='" + e_name + "' MERGE (p)-[r:" + label + "]->(q)"self.graph.run(cql)except Exception as e:passdef getValue(self, key, data):if key in data:return data[key]return ""def init(self):# 实体# 疾病diseases = []# 科室departments = []# 疾病症状symptoms = []# 治疗方式cureWays = []# 检查项目checks = []# 药物drugs = []# 易感染人群crowds = []# 食物foods = []# 关系# 疾病科室diseaseDepartmentRelations = []# 疾病症状diseaseSymptomRelations = []# 疾病治疗diseaseCureWayRelations = []# 疾病检查diseaseCheckRelations = []# 疾病用药diseaseDrugRelations = []# 疾病易感染人群diseaseCrowdRelations = []# 疾病宜吃食物diseaseSuitableFoodRelations = []# 疾病忌吃食物diseaseTabooFoodRelations = []# 疾病并发症diseaseDiseaseRelations = []print("====数据抽取======")with open(self.data_path, 'r', encoding='utf8') as f:for line in tqdm(f.readlines(), ncols=80):data = json.loads(line)# 疾病实体disease = {"name": data["name"],"desc": self.getValue("desc", data),"prevent": self.getValue("prevent", data),"cause": self.getValue("cause", data),"get_prob": self.getValue("get_prob", data),"get_way": self.getValue("get_way", data),"cure_lasttime": self.getValue("cure_lasttime", data),"cured_prob": self.getValue("cured_prob", data),"cost_money": self.getValue("cost_money", data),}diseases.append(disease)# 科室if "cure_department" in data:for department in data["cure_department"]:# 疾病科室关系diseaseDepartmentRelations.append({"s_name": data["name"],"e_name": department})# 科室实体property = {"name": department}if property not in departments:departments.append(property)# 症状if "symptom" in data:for symptom in data["symptom"]:# 疾病科室关系diseaseSymptomRelations.append({"s_name": data["name"],"e_name": symptom})# 症状实体property = {"name": symptom}if property not in symptoms:symptoms.append(property)# 治疗方式if "cure_way" in data:for cure_way in data["cure_way"]:# 疾病科室关系diseaseCureWayRelations.append({"s_name": data["name"],"e_name": cure_way})# 治疗方式实体property = {"name": cure_way}if property not in cureWays:cureWays.append(property)# 检查项目if "check" in data:for check in data["check"]:# 疾病科室关系diseaseCheckRelations.append({"s_name": data["name"],"e_name": check})# 检查项目实体property = {"name": check}if property not in checks:checks.append(property)# 一般用药if "common_drug" in data:for common_drug in data["common_drug"]:# 疾病科室关系diseaseDrugRelations.append({"s_name": data["name"],"e_name": common_drug})# 用药实体property = {"name": common_drug}if property not in drugs:drugs.append(property)# 易感染人群if "easy_get" in data:easy_get = data["easy_get"]# 疾病科室关系diseaseCrowdRelations.append({"s_name": data["name"],"e_name": easy_get})# 易感染人群实体property = {"name": easy_get}if property not in crowds:crowds.append(property)# 宜吃食物if "recommand_eat" in data:for recommand_eat in data["recommand_eat"]:# 疾病科室关系diseaseSuitableFoodRelations.append({"s_name": data["name"],"e_name": recommand_eat})# 食物实体property = {"name": recommand_eat}if property not in foods:foods.append(property)# 忌吃食物if "not_eat" in data:for not_eat in data["not_eat"]:# 疾病科室关系diseaseTabooFoodRelations.append({"s_name": data["name"],"e_name": not_eat})# 食物实体property = {"name": not_eat}if property not in foods:foods.append(property)# 并发症if "acompany" in data:for acompany in data["acompany"]:# 疾病科室关系diseaseDiseaseRelations.append({"s_name": data["name"],"e_name": acompany})# 疾病self.saveEntity("disease", diseases)# 科室self.saveEntity("department", departments)# 疾病症状self.saveEntity("symptom", symptoms)# 治疗方式self.saveEntity("cureWay", cureWays)# 检查项目self.saveEntity("check", checks)# 药物self.saveEntity("drug", drugs)# 易感染人群self.saveEntity("crowd", crowds)# 食物self.saveEntity("food", foods)# 关系# 疾病科室self.saveRelation("disease", "department", "diseaseDepartmentRelations", diseaseDepartmentRelations)# 疾病症状self.saveRelation("disease", "symptom", "diseaseSymptomRelation", diseaseSymptomRelations)# 疾病治疗self.saveRelation("disease", "cureWay", "diseaseCureWayRelation", diseaseCureWayRelations)# 疾病检查self.saveRelation("disease", "check", "diseaseCheckRelation", diseaseCheckRelations)# 疾病用药self.saveRelation("disease", "drug", "diseaseDrugRelation", diseaseDrugRelations)# 疾病易感染人群self.saveRelation("disease", "crowd", "diseaseCrowdRelation", diseaseCrowdRelations)# 疾病宜吃食物self.saveRelation("disease", "food", "diseaseSuitableFoodRelation", diseaseSuitableFoodRelations)# 疾病忌吃食物self.saveRelation("disease", "food", "diseaseTabooFoodRelation", diseaseTabooFoodRelations)# 疾病并发症self.saveRelation("disease", "disease", "diseaseDiseaseRelation", diseaseDiseaseRelations)if __name__ == '__main__':kg_host = "127.0.0.1"kg_port = 7474kg_user = "neo4j"kg_password = "123456"data_path = "./data/medical.json"kg = CreateKG(kg_host, kg_port, kg_user, kg_password, data_path)kg.init()

运行之后可以看到处理的进度:

在这里插入图片描述

等待处理结束后就可以在图谱中看到构建后的效果了:

在这里插入图片描述

五、数据探索测试

鼻炎的病症描述:

match (n:disease) where n.name = '鼻炎' return n.desc

在这里插入图片描述

鼻炎所属的科室:

match (n:disease)-[e:diseaseDepartmentRelations]->(n1:department) where n.name = '鼻炎' return n,n1

在这里插入图片描述

鼻炎的症状:

match (n:disease)-[e:diseaseSymptomRelation]->(n1:symptom) where n.name = '鼻炎' return n,n1

在这里插入图片描述

鼻炎的治疗方式:

match (n:disease)-[e:diseaseCureWayRelation]->(n1:cureWay) where n.name = '鼻炎' return n,n1

在这里插入图片描述

鼻炎应该用什么药:

match (n:disease)-[e:diseaseDrugRelation]->(n1:drug) where n.name = '鼻炎' return n,n1

在这里插入图片描述

相关文章:

ChatGPT结合知识图谱构建医疗问答应用 (一) - 构建知识图谱

一、ChatGPT结合知识图谱 在本专栏的前面文章中构建 ChatGPT 本地知识库问答应用,都是基于词向量检索 Embedding 嵌入的方式实现的,在传统的问答领域中,一般知识源采用知识图谱来进行构建,但基于知识图谱的问答对于自然语言的处理…...

C++ 类和对象

面向过程/面向对象 C语言是面向过程,关注过程,分析出求解问题的步骤,通过函数调用逐步解决问题 C是基于面对对象的,关注的是对象——将一件事拆分成不同的对象,依靠对象之间的交互完成 引入 C语言中结构体只能定义…...

c# 此程序集中已使用了资源标识符

严重性 代码 说明 项目 文件 行 禁止显示状态 错误 CS1508 此程序集中已使用了资源标识符“BMap.NET.WindowsForm.BMapControl.resources” BMap.NET.WindowsForm D:\MySource\Decompile\BMap.NET.WindowsForm\CSC 1 活动 运行程序时&a…...

WPF实战学习笔记30-登录、注册服务添加

登录、注册服务添加 添加注册数据类型添加注册UI修改bug UserDto的UserName更改为可null类型Resgiter 添加加密方法修改控制器 添加注册数据类型 添加文件MyToDo.Share.Models.ResgiterUserDto.cs using System; using System.Collections.Generic; using System.Linq; us…...

GDAL C++ API 学习之路 OGRGeometry 圆弧类 OGRCircularString

OGRCircularString Class <ogrsf_frmts.h> OGRCircularString 类是 OGR 几何库中的一个类&#xff0c;用于表示圆弧字符串&#xff08;circular string&#xff09;类型的几何图形。圆弧字符串是由一系列圆弧段组成的几何图形&#xff0c;每个圆弧段由三个点定义…...

机器学习:异常检测

问题定义 anomaly&#xff0c;outlier&#xff0c; novelty&#xff0c; exceptions 不同的方法使用不同的名词定义这类问题。 应用 二分类 假如只有正常的数据&#xff0c;而异常的数据的范围非常广的话&#xff08;无法穷举&#xff09;&#xff0c;二分类这些不好做。另外就…...

flask中的蓝图

flask中的蓝图 在 Flask 中&#xff0c;蓝图&#xff08;Blueprint&#xff09;是一种组织路由和服务的方法&#xff0c;它允许你在应用中更灵活地组织代码。蓝图可以大致理解为应用或者应用中的一部分&#xff0c;可以在蓝图中定义路由、错误处理程序以及静态文件等。然后可以…...

Spring Cloud+Spring Boot+Mybatis+uniapp+前后端分离实现知识付费平台免费搭建

Java版知识付费-轻松拥有知识付费平台 多种直播形式&#xff0c;全面满足直播场景需求 公开课、小班课、独立直播间等类型&#xff0c;满足讲师个性化直播场景需求&#xff1b;低延迟、双向视频&#xff0c;亲密互动&#xff0c;无论是互动、答疑&#xff0c;还是打赏、带货、…...

uniapp 瀑布流 (APP+H5+微信小程序)

WaterfallsFlow.vue <template><view class"wf-page" :class"props?.paddingC ? paddingC : "><!-- left --><view><view id"left" ref"left" v-if"leftList.length"><viewv-for…...

医疗小程序:提升服务质量与效率的智能平台

在医疗行业&#xff0c;公司小程序成为提高服务质量、优化管理流程的重要工具。通过医疗小程序&#xff0c;可以方便医疗机构进行信息传播、企业展示等作用&#xff0c;医疗机构也可以医疗小程序提供更便捷的预约服务&#xff0c;优化患者体验。 医疗小程序的好处 提升服务质量…...

ComPDFKit 转档SDK OCR表格识别功能

我们非常高兴地宣布&#xff0c;适用于 Windows、iOS、Android 和服务器的 ComPDFKit 转档SDK 1.8.0 现已发布&#xff01;在该版本中&#xff0c;OCR 功能支持了表格识别&#xff0c;优化了OCR文字识别率。PDF to HTML 优化了html 文件结构&#xff0c;使转换后的 HTML 文件容…...

华为OD机考--阿里巴巴黄金箱

题目内容 贫如洗的樵夫阿里巴巴在去砍柴的路上&#xff0c;无意中发现了强盗集团的藏宝地&#xff0c;藏宝地有编号从0~N的箱子每个箱子上面贴有一个数字箱子中可能有一个黄金宝箱。 黄金宝箱满足排在它之前的所有箱子数字和等于排在它之后的所有箱子数字之和; 一个箱子左边部分…...

mybatis-config.xml-配置文件详解

文章目录 mybatis-config.xml-配置文件详解说明文档地址:配置文件属性解析properties 属性应用实例 settings 全局参数定义应用实例 typeAliases 别名处理器举例说明 typeHandlers 类型处理器environments 环境environment 属性应用实例 mappers配置 mybatis-config.xml-配置文…...

【雕爷学编程】MicroPython动手做(18)——掌控板之声光传感器

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…...

Ribbon源码

学了feign源码之后感觉&#xff0c;这部分还是按运行流程分块学合适。核心组件什么的&#xff0c;当专业术语学妥了。序章&#xff1a;认识真正のRibbon 但只用认识一点点 之前我们学习Ribbon的简单使用时&#xff0c;都是集成了Eureka-client或者Feign等组件&#xff0c;甚至在…...

Linux下在终端输入密码隐藏方法

Linux系统中&#xff0c;如何将在终端输入密码时将密码隐藏&#xff1f; 最近做简单的登录界面时&#xff0c;不做任何操作的话&#xff0c;在终端输入密码的同时也会显示输入的密码是什么&#xff0c;这样对于隐蔽性和使用都有不好的体验。那么我就想到将密码用字符*隐藏起来…...

【ARM 常见汇编指令学习 3 -- ARM64 无符号位域提取指令 UBFX】

文章目录 ARM64 无符号位域提取指令 上篇文章&#xff1a;ARM 常见汇编指令学习 2 – 存储指令 STP 与 LDP 下篇文章&#xff1a;ARM 常见汇编指令学习 4 – ARM64 比较指令 cbnz 与 b.ne 区别 ARM64 无符号位域提取指令 在代码中如何监控寄存器的某1bit&#xff0c; 或者某几…...

求分享如何批量压缩视频的容量的方法

视频内存过大&#xff0c;不但特别占内存&#xff0c;而且还会使手机电脑出现卡顿的现象&#xff0c;除此之外&#xff0c;如果我们想发送这些视频文件可能还会因为内存太大无法发送。因此&#xff0c;我们可以批量地压缩视频文件的内存大小&#xff0c;今天小编要来分享一招&a…...

ChatGPT 是如何工作的:从预训练到 RLHF

欢迎来到人工智能的未来&#xff1a;生成式人工智能&#xff01;您是否想知道机器如何学习理解人类语言并做出相应的反应&#xff1f;让我们来看看ChatGPT ——OpenAI 开发的革命性语言模型。凭借其突破性的 GPT-3.5 架构&#xff0c;ChatGPT 席卷了世界&#xff0c;改变了我们…...

KafKa脚本操作

所有操作位于/usr/local/kafka_2.12-3.5.1/bin。 rootubuntu2203:/usr/local/kafka_2.12-3.5.1/bin# pwd /usr/local/kafka_2.12-3.5.1/bin rootubuntu2203:/usr/local/kafka_2.12-3.5.1/bin# ls connect-distributed.sh kafka-delegation-tokens.sh kafka-mirror-mak…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...