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

【RealEarthStudio】应用2:数据集渲染任务管理——后端搭建

数据集渲染任务管理——后端搭建

  • 引言
  • 一、主要功能
  • 二、实现步骤
    • 2.1 创建App
      • (1)使用命令行创建App
      • (2)注册App
      • (3)配置路由
    • 2.2 创建Model
      • (1)配置媒体文件地址
      • (2)创建model
      • (3)迁移数据库
    • 2.3 在Admin中注册模型
    • 2.4 效果

引言

计算机专业硕士在读,主要研究方向是特定目标大斜视角目标检测与定位。因为要做的是特定目标,公开数据集较少,经过多方考虑还是决定要自建数据集。最终考虑的解决方案还是Blender+Python API的方式,项目起名叫RealEarthStudio
这系列文章主要对开发过程进行记录,方便我个人后续查看,也给相类似方向的同学提供一个思路。

【项目目录】:项目目录链接


一、主要功能

  • 功能:数据集渲染任务管理——后端搭建。

  • 背景:现在开始开发第二个应用,主要实现数据集渲染任务管理。

  • 效果

  • 码云项目链接:https://gitee.com/charlsewyq/RealEarthStudio


二、实现步骤

2.1 创建App

(1)使用命令行创建App

python manage.py startapp app2_rendering_task

(2)注册App

  • App目录下编辑apps文件:app2_rendering_task/apps.py
fromdjango.appsimportAppConfigclassApp2RenderingTaskConfig(AppConfig):default_auto_field="django.db.models.BigAutoField"name="app2_rendering_task"verbose_name="🏷️ 应用2:数据集渲染任务管理模块"
  • 主项目目录settings.py中添加app:
INSTALLED_APPS=[...,# 我的应用'app2_rendering_task.apps.App2RenderingTaskConfig',]

(3)配置路由

  • App目录下创建urls.py
fromdjango.urlsimportpathfrom.importviews app_name='app2_rendering_task'urlpatterns=[# 子路由]
  • 主项目目录urls.py修改:
fromdjango.contribimportadminfromdjango.urlsimportpath,include urlpatterns=[...# app2: 数据集渲染任务管理模块path("api/app2/",include("app2_rendering_task.urls")),]

2.2 创建Model

我想创建渲染任务Model,包含以下字段:

  • 渲染ID:字符串类型,模型的唯一标识,自动生成
  • 渲染时间:时间类型,上传模型的时间,根据后台时间自动记录
  • 目标模型:多对多,对应目标模型Modelapp1_model_management.TargetModel
  • 场景模型:多对多,对应场景模型Modelapp1_model_management.SceneModel
  • 日光方位角:浮点类型,阳光照射的方位角(限制为0-360°,默认为0°)
  • 日光高低角:浮点类型,阳光照射的高低角(限制为0-90°,默认为90°)
  • 相机距离:JSON类型,相机距离目标模型的距离数组(限制为正值)
  • 相机高低角:JSON类型,相机照射的高低角数组(限制为0-90°)
  • 相机方位角间隔:浮点类型,阳光照射的方位角(限制为0-360°,默认为45°)
  • 渲染图像分辨率(宽):整型,渲染图像的宽。
  • 渲染图像分辨率(高):整型,渲染图像的宽。
  • 渲染图像像素:计算属性,渲染图像的像素值。
  • 模型器类别:字符串类型,渲染器类别(EEVEE或CYCLES)
  • 渲染图像地址:文件地址类型,只读,用于存储渲染结果,删除数据时自动删除对应文件夹中的文件

(1)配置媒体文件地址

  • 主项目目录创建文件夹:media
  • settings.py中添加以下内容:
MEDIA_URL='/media/'MEDIA_ROOT=os.path.join(BASE_DIR,'media')
  • 配置媒体文件服务:
    主项目目录下编辑urls.py文件:
...# 只在DEBUG模式下提供媒体文件服务ifsettings.DEBUG:urlpatterns+=static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)

(2)创建model

还需要完成以下功能:

  • 自动生成UUID,确保模型ID不重复
  • 自动记录时间
  • 把目标模型和
  • 删除数据时同步删除模型文件
  • 修改文件数据时替换模型文件

App目录下编辑model文件:app2_rendering_task/models.py

importosimportuuidfromdjango.dbimportmodelsfromdjango.utilsimporttimezonefromdjango.core.exceptionsimportValidationErrorimportshutilfromapp1_model_management.modelsimportTargetModel,SceneModel# ====== 验证器 ======defvalidate_azimuth(value):ifnot(0<=value<=360):raiseValidationError("方位角必须在 0° 到 360° 之间。")defvalidate_elevation(value):ifnot(0<=value<=90):raiseValidationError("高低角必须在 0° 到 90° 之间。")defvalidate_positive_number_list(value):"""验证是否为正数列表"""ifnotisinstance(value,list):raiseValidationError("必须是一个列表。")foriteminvalue:ifnotisinstance(item,(int,float))oritem<=0:raiseValidationError("所有值必须是正数。")defvalidate_elevation_list(value):"""验证高低角列表 0-90"""ifnotisinstance(value,list):raiseValidationError("必须是一个列表。")foriteminvalue:ifnotisinstance(item,(int,float))ornot(0<=item<=90):raiseValidationError("所有高低角必须在 0° 到 90° 之间。")# ====== 模型 ======defrendered_result_path(instance,filename):"""场景模型上传路径"""returnos.path.join("Render",f"{instance.render_time}-{instance.render_id}")classRenderingTask(models.Model):RENDERER_CHOICES=[('EEVEE','EEVEE'),('CYCLES','Cycles'),]# 任务信息render_id=models.UUIDField("渲染ID",default=uuid.uuid4,editable=False,unique=True,help_text="渲染任务的唯一标识")render_time=models.DateTimeField(verbose_name="渲染时间",default=timezone.now)# 模型target_models=models.ManyToManyField(TargetModel,verbose_name="目标模型",blank=True,related_name="rendering_tasks")scene_models=models.ManyToManyField(SceneModel,verbose_name="场景模型",blank=True,related_name="rendering_tasks")# 日光参数sun_azimuth=models.FloatField("日光方位角",default=0.0,validators=[validate_azimuth],help_text="阳光照射的方位角(0°-360°)")sun_elevation=models.FloatField("日光高低角",default=90.0,validators=[validate_elevation],help_text="阳光照射的高低角(0°-90°)")# 相机参数camera_distances=models.JSONField("相机距离",default=list,blank=True,validators=[validate_positive_number_list],help_text="相机到目标的距离列表(正值)")camera_elevations=models.JSONField("相机高低角",default=list,blank=True,validators=[validate_elevation_list],help_text="相机高低角列表(0°-90°)")camera_rotation_step=models.FloatField("相机方位角间隔",default=45.0,validators=[validate_azimuth],help_text="相机方位角采样间隔(0°-360°)")# 渲染分辨率image_width=models.PositiveIntegerField("渲染图像分辨率(宽)",default=1920)image_height=models.PositiveIntegerField("渲染图像分辨率(高)",default=1080)# 渲染器类别renderer_type=models.CharField("渲染器类别",max_length=10,choices=RENDERER_CHOICES,default='EEVEE')# 渲染结果文件rendered_result=models.FileField("渲染图像地址",upload_to=rendered_result_path,blank=True,null=True,help_text="系统自动生成的渲染结果图像(只读)")classMeta:verbose_name="01-渲染任务"verbose_name_plural="01-渲染任务"ordering=['-render_time']def__str__(self):returnf"{self.render_id}"@propertydefimage_pixels(self):"""计算属性:总像素数"""returnself.image_width*self.image_heightdefsave(self,*args,**kwargs):"""可选:在保存前调用 full_clean() 进行验证"""self.full_clean()super().save(*args,**kwargs)defdelete(self,*args,**kwargs):""" 重写 delete 方法: 1. 先删除关联的渲染输出文件夹 2. 再调用父类 delete 删除数据库记录 """ifself.rendered_result:# 获取文件的绝对路径folder_dir=self.rendered_result.path# 如果文件存在则删除ifos.path.isdir(folder_dir):shutil.rmtree(folder_dir)# 调用父类的delete方法删除数据库记录super().delete(*args,**kwargs)

(3)迁移数据库

# 生成迁移文件python manage.py makemigrations app2_rendering_task# 应用迁移python manage.py migrate app2_rendering_task

2.3 在Admin中注册模型

App目录下编辑admin文件:app2_rendering_task/admin.py

fromdjango.contribimportadminfrom.modelsimport*fromdjango.utils.safestringimportmark_safe@admin.register(RenderingTask)classRenderingTaskAdmin(admin.ModelAdmin):list_display=['render_id','render_time','renderer_type','image_width','image_height','render_progress_display']search_fields=['render_id']list_filter=['renderer_type','render_time']readonly_fields=['render_id','render_time','render_progress','rendered_result']# 字段分组显示fieldsets=(('任务信息',{'fields':('render_id','render_time','renderer_type','render_progress')}),('模型配置',{'fields':('target_models','scene_models')}),('光照参数',{'fields':('sun_azimuth','sun_elevation')}),('相机参数',{'fields':('camera_distances','camera_elevations','camera_rotation_step')}),('图像设置',{'fields':('image_width','image_height')}),('渲染结果',{'fields':('rendered_result',)}))@admin.display(description="渲染状态")defrender_progress_display(self,obj):ifobj.render_progress==0:# 如果状态是pending,显示一个链接returnmark_safe(f'<a href="#">开始渲染</a>')else:# 否则显示当前状态returnf"{obj.render_progress}%"

2.4 效果



http://www.cnnetsun.cn/news/92328.html

相关文章:

  • 备赛三--
  • 高并发时代的“确定性”挑战——为何稳定性正在成为 JVM 的下一场核心竞争?
  • C语言之最大公约数和最小公倍数问题
  • LobeChat能否对接Telegram Bot?跨平台消息同步实现
  • AI如何用博图加速工业自动化开发
  • C++:二叉搜索树(BST)完全指南(从概念原理、核心操作到底层实现)
  • Splashtop AEM 在 G2冬季报告中斩获“最佳预估 ROI”殊荣
  • 赋能传统硬件:具身智能如何激活工业机器人的二次生命
  • 【模板:求组合数】信息学奥赛一本通 1648:【例 1】「NOIP2011」计算系数 | 1866:【11NOIP提高组】计算系数 | 洛谷 P1313 [NOIP 2011 提高组] 计算系数
  • 金运环球:金价高位回落,非农与零售数据即将来袭
  • 活动力度大的门头招牌企业
  • 【毕业设计】基于JavaWeb的兽医站管理系统的设计与实现(源码+文档+远程调试,全bao定制等)
  • Java毕设选题推荐:基于JavaWeb的兽医站管理系统的设计与实现现代化兽医站管理系统【附源码、mysql、文档、调试+代码讲解+全bao等】
  • Arduino配置8266开发板
  • 【课程设计/毕业设计】基于SpringBoot+Vue茶叶销售系统的设计与实现基于Java语言的茶叶销售系统的前端设计与实现【附源码、数据库、万字文档】
  • 41. 缺失的第一个正数
  • 打了一堆板子,才发现是VDD_EXT的锅
  • 技术亲民倒计时!飞猫 RedCap 轻量化 5G 随身 WiFi 即将上市!
  • # 深入 Ascend C 内存模型:掌握UB、GM与流水线优化,打造极致AI算子
  • 冥想第一千七百三十五天(1735)
  • 代理IP和普通IP有什么区别?这篇文章帮你捋明白
  • 体系结构分类和指令系统
  • 基于AI数字人系统源码的低成本开发方案与实践经验
  • SQL 调优全解:从 20 秒到 200 ms 的 6 步实战笔记(附脚本)
  • YOLO目标检测模型如何对接Apipost平台
  • 简单的创建一个Spring Boot网页
  • 鼠标滚轮缩放图片:前端实现高清无损放大技巧(附实战代码)
  • Numpy库实践2_索引和数组的操作
  • 图解 - 红黑树(插入)
  • Memgraph 全新 AI 图工具包:一键构建 GraphRAG 聊天机器人,实现快速上下文感知响应