创建的知识图谱可以参考上一篇博客:使用Protege创建机器人的知识图谱_阿呀三的博客-CSDN博客
接下来我们通过python完成对x,y,z坐标的读取和写入
完整代码在最下方
第一步:安装读取rdf文件的库:
pip install rdflib
# conda环境使用
conda install rdflib
第二步骤:导入相关的库
from rdflib import Graph, Namespace, RDF, Literal
第三步:加载知识图谱并且导入命名空间
g = Graph()
g.parse("C:\\Users\\46494\\Desktop\\yolov5-6.0\\图谱F.rdf") # 填入知识图谱的路径
# 创建命名空间
ns = Namespace("http://www.semanticweb.org/46494/ontologies/2023/3/untitled-ontology-14#") #命名空间就是软件上方的地址,可以看见的
如图所示,记得末尾有一个”#“不要漏掉了
第四步:读取知识图谱所需要的内容
query = f"""
PREFIX : <{self.ns}>
SELECT ?Red ?Red_position ?x_position ?y_position ?z_position
WHERE {{
?Red rdf:type :Block .
?Red_position rdf:type :Position .
?Red :hasPosition :Red_position .
?Red_position :x_position ?x_position .
?Red_position :y_position ?y_position .
?Red_position :z_position ?z_position .
FILTER (str(?Red_position)= "{ns}Red_position" )
}}
"""
"""
Block有实例Red
Position有实例Red_position
Red实例和Red_position有属性hasPosition
Red_position有数据属性x_position
Red_position有数据属性y_position
Red_position有数据属性z_position
指定搜索Red_position的x、y、z_position,因为Purple和Green共用一个x、y、z_position
"""
第五步:输出查询结果
result = g.query(query) # result存储查询到的值
# 输出查询结果
for row in result: # 在查询到的值里进行搜索需要输出的值
print("更新前坐标:", f"X: {row[2]}, Y: {row[3]}, Z: {row[4]}")
第六步:更新坐标信息
# 更新坐标信息
new_x = 10
new_y = 20
new_z = 30
for row in result:
Position2 = row[1]
g.set((Position2, ns.x_position, Literal(new_x)))
g.set((Position2, ns.y_position, Literal(new_y)))
g.set((Position2, ns.z_position, Literal(new_z)))
第七步:保存更新后的图谱,并且输出更新后的坐标信息
# 保存更新后的知识图谱
g.serialize(destination="图谱F.rdf", format="xml")
# 输出更新后的坐标信息
result = g.query(query)
for row in result:
print("更新后坐标:", f"X: {row[2]}, Y: {row[3]}, Z: {row[4]}")
根据自己的需要进行改进,将代码封装进函数方便自己调用,完整代码如下(版本1):
from rdflib import Graph, Namespace, RDF, Literal
# 读取知识图谱(本体)文件
g = Graph()
g.parse("C:/Users/46494/Desktop/图谱F.rdf") # 将 'your_ontology_file.owl' 替换为您的本体文件名
# 创建命名空间
ns = Namespace("http://www.semanticweb.org/46494/ontologies/2023/3/untitled-ontology-14#")
object = 'Green' # 创建变量,需要什么就读取什么
def findObject(object):
position = f"{object}_position"
query = f"""
PREFIX : <{ns}>
SELECT ?{object} ?{position} ?x_position ?y_position ?z_position
WHERE {{
?{object} rdf:type :Block .
?{position} rdf:type :Position .
?{object} :hasPosition :{position} .
?{position} :x_position ?x_position .
?{position} :y_position ?y_position .
?{position} :z_position ?z_position .
FILTER (str(?{position})= "{ns}{position}" )
}}
"""
result = g.query(query)
# 输出查询结果
for row in result:
print("更新前坐标:", f"X: {row[2]}, Y: {row[3]}, Z: {row[4]}")
# 更新坐标信息
new_x = 10
new_y = 20
new_z = 30
for row in result:
Position2 = row[1] # row[1]是一个地址
g.set((Position2, ns.x_position, Literal(new_x))) # 这里先调用地址定位,然后更新坐标信息
g.set((Position2, ns.y_position, Literal(new_y)))
g.set((Position2, ns.z_position, Literal(new_z)))
# 保存更新后的知识图谱
g.serialize(destination="图谱F.rdf", format="xml")
# 输出更新后的坐标信息
result = g.query(query)
for row in result:
print("更新后坐标:", f"X: {row[2]}, Y: {row[3]}, Z: {row[4]}")
findObject(object)
版本2:封装进类,将读取和更新写进两个函数,并且当我们没有识别坐标时,坐标的读取值为None
from rdflib import Graph, Namespace, RDF, Literal
# 创建类,方便在其他程序中调用
class ontology:
# 初始化函数
def __init__(self):
self.g = Graph()
self.g.parse("C:\\Users\\46494\\Desktop\\yolov5-6.0\\图谱F.rdf") # 将 'your_ontology_file.owl' 替换为您的本体文件名
# 创建命名空间
self.ns = Namespace("http://www.semanticweb.org/46494/ontologies/2023/3/untitled-ontology-14#")
# 在启动程序前,设置所有对象的坐标为 None,检测到后自动更新
for obj in self.g.subjects(RDF.type, self.ns.Block):
position = self.g.value(obj, self.ns.hasPosition)
self.g.set((position, self.ns.x_position, Literal(None)))
self.g.set((position, self.ns.y_position, Literal(None)))
self.g.set((position, self.ns.z_position, Literal(None)))
# 读取坐标函数
def findObject(self,object):
position = f"{object}_position"
query = f"""
PREFIX : <{self.ns}>
SELECT ?{object} ?{position} ?x_position ?y_position ?z_position
WHERE {{
?{object} rdf:type :Block .
?{position} rdf:type :Position .
?{object} :hasPosition :{position} .
?{position} :x_position ?x_position .
?{position} :y_position ?y_position .
?{position} :z_position ?z_position .
FILTER (str(?{position})= "{self.ns}{position}" )
}}
"""
result = self.g.query(query)
# 输出查询结果
for row in result:
print("更新前坐标:", f"X: {row[2]}, Y: {row[3]}, Z: {row[4]}")
# 更新坐标函数
def updateObject(self,object,x,y):
position = f"{object}_position"
query = f"""
PREFIX : <{self.ns}>
SELECT ?{position} ?x_position ?y_position ?z_position
WHERE {{
?{object} rdf:type :Block .
?{position} rdf:type :Position .
?{object} :hasPosition :{position} .
?{position} :x_position ?x_position .
?{position} :y_position ?y_position .
?{position} :z_position ?z_position
FILTER (str(?{position})= "{self.ns}{position}" )
}}
"""
result = self.g.query(query)
new_z = 30
for row in result:
Position2 = row[0]
self.g.set((Position2, self.ns.x_position, Literal(x)))
self.g.set((Position2, self.ns.y_position, Literal(y)))
self.g.set((Position2, self.ns.z_position, Literal(new_z)))
# 保存更新后的知识图谱
self.g.serialize(destination="图谱F.rdf", format="xml")
# 输出更新后的坐标信息
result = self.g.query(query)
for row in result:
print(f"{object}:", f"X: {row[1]}, Y: {row[2]}, Z: {row[3]}")
# 读取知识图谱(本体)文件
if __name__ == "__main__":
object = 'Green'
ot = ontology()
ot.findObject(object)
ot.updateObject(object,x=1,y=10) # 项目需要的z是不变的,这里我们不进行z的更新