Blenderproc渲染6D位姿估计数据集

https://github.com/DLR-RM/BlenderProc/tree/main/examples/datasets/bop_challenge

目录

1.3d渲染原理

2.步骤

3.代码

生成mask_all

4.难例渲染

物体高反光​编辑​编辑强弱灯光(明暗)​编辑​编辑​编辑物体xyz范围缩小

物体重复

干扰物(自定义干扰物遮挡)​

物体添加dust

指定遮挡

模糊


1.3d渲染原理

https://zhuanlan.zhihu.com/p/616649293

1.几何计算

将3D模型转化为计算机可处理的数据结构,例如三角网格,为后续计算做准备

2.光照计算

根据光源的位置、颜色和光照强度等参数,计算每个像素的颜色和亮度。这个过程需要考虑光照的反射、漫反射、高光反射等多种因素,以模拟真实世界的光照效果

3.映射: 将2D纹理贴到3D模型表面上,使其更加真实。这个过程需要将2D 纹理坐标与3D模型表面坐标进行映射,以便将纹理正确地贴到3D模型表面上。

4.像素渲染:

将计算得到的颜色和亮度信息应用到每个像素上,生成最终的2D 图像。这个过程需要将计算得到的颜色值经过抗锯齿等处理,以消除锯齿和模糊等现象,使得图像更加真实。

2.步骤

  1. 使用 3D 建模软件创建 3D 对象或模型。

有多种方法可以创建 3D 模型或整个场景。一些雕刻应用程序允许您创建和塑造多边形,最终形成 3D 资产。例如,这种类型的建模可能特别适合创建有机资产(例如植物或人物),因为它非常适合对有些不规则的形状进行艺术诠释。

存在这种方法的替代方法。其他建模工具专注于在三维空间中创建边和表面,而不是多边形。以这种方式创建 3D 资产可实现极高的数学精度,此类工具通常用于工业设计或计算机辅助设计 (CAD) 建模。

或者,您可能会选择使用专用工具“扫描”现有的现实生活中的对象——从此类扫描中捕获的数据将使您能够在 3D 空间中重新创建对象。或者您可能更喜欢走程序生成路线,在这种路线中,您的软件会根据一组先前建立的数学规则为您塑造一个模型。

无论您如何创建 3D 模型,下一步都是纹理化。

2.为3D物体添加材质。

多边形定义 3D 对象的形状,但它们本身缺乏颜色或表面细节。艺术家能够为 3D 对象中的每个多边形分配纹理。纹理可以是简单的单色,也可以模拟任何表面的外观,从岩石或木材等天然材料到工业金属或塑料表面。

一个 3D 对象可以由数千个(如果不是数百万个)多边形组成。该对象可能看起来具有厨房搅拌机的现代工业光滑度或大象的粗糙皮肤,但其核心仍然是一个由多边形和有些空白的表面组成的对象。然而,使用正确的 3D 材料,可以创建 3D 深度的错觉。这些纹理远不止简单地为物体添加反射率或颜色——纹理可以添加精细的细节,例如服装面料的缝合,或工业金属表面边缘的铆钉排。如果您要手动将它们添加到对象的几何体中,那么创建这些细节将非常耗时。

3. 为 3D 环境添加照明。

3D 对象需要看起来像是存在于现实世界中。对于建筑渲染和建筑可视化等常见用例尤其如此,它们可以将基本的平面图变成对未来的清晰愿景。

逼真的光源在将多边形对象的集合变成看起来真实的空间方面发挥着重要作用。但是 3D 艺术家通常不会自己在光线或阴影中作画。相反,3D 场景包括照亮各种对象的方向、强度和光源类型的设置。

  1. 渲染 3D 图像。

一旦创建了 3D 对象并对其进行了纹理处理,并且照亮了环境,3D 渲染过程就开始了。这是一个计算机驱动的过程,本质上是从您定义的角度拍摄场景的“快照”。结果是 3D 场景的 2D 图像。

渲染软件可以创建单个图像,也可以快速连续地渲染多个图像以创建实时运动的错觉。

渲染不是一个统一的过程——有许多方法可以使用,例如实时、光线追踪等,它们会影响渲染的质量。、

3.代码

blenderproc run examples/datasets/bop_challenge/main_lm_upright.py 
/media/px_dataset1/fuzhao_datasets/paxini_model 
/home/fuzhao/poseEstimate/FFB6D/ffb6d/blender_project/BlenderProc/cc_texture_dataset 
/home/fuzhao/blender/out2 --num_scenes=500

生成mask_all

需要指定场景,修改bop渲染后数据的目录,和模型文件名id对应的图片名id

Write mask: https://github.com/DLR-RM/BlenderProc/blob/main/blenderproc/python/writer/BopWriterUtility.py

https://github.com/thodan/bop_toolkit/blob/master/scripts/calc_gt_masks.py

if calc_mask_info_coco:
        # Set up the bop toolkit
        SetupUtility.setup_pip(["git+https://github.com/thodan/bop_toolkit", "PyOpenGL==3.1.0"])

        # determine which objects to add to the vsipy renderer
        # for numpy>=1.20, np.float is deprecated: https://numpy.org/doc/stable/release/1.20.0-notes.html#deprecations
        np.float = float

        # Determine for which directories mask_info_coco has to be calculated
        chunk_dirs = sorted(glob.glob(os.path.join(chunks_dir, '*')))
        chunk_dirs = [d for d in chunk_dirs if os.path.isdir(d)]
        chunk_dir_ids = [d.split('/')[-1] for d in chunk_dirs]
        chunk_dirs = chunk_dirs[chunk_dir_ids.index(f"{starting_chunk_id:06d}"):]

        # convert all objects to trimesh objects
        trimesh_objects = {}
        for obj in dataset_objects:
            if obj.get_cp('category_id') in trimesh_objects:
                continue
            if isinstance(obj, Link):
                if not obj.visuals:
                    continue
                if len(obj.visuals) > 1:
                    warnings.warn('BOP Writer only supports saving annotations of one visual mesh per Link')
            trimesh_obj = obj.mesh_as_trimesh()
            # we need to create a double-sided material to be able to render non-watertight meshes
            # the other parameters are defaults, see
            # https://github.com/mmatl/pyrender/blob/master/pyrender/mesh.py#L216-L223
            material = pyrender.MetallicRoughnessMaterial(alphaMode='BLEND', baseColorFactor=[0.3, 0.3, 0.3, 1.0],
                                                          metallicFactor=0.2, roughnessFactor=0.8, doubleSided=True)
            # here we also add the scale factor of the objects. the position of the pyrender camera will change based
            # on the initial scale factor of the objects and the saved annotation format
            if not np.all(np.isclose(np.array(obj.blender_obj.scale), obj.blender_obj.scale[0])):
                print("WARNING: the scale is not the same across all dimensions, writing bop_toolkit annotations with "
                      "the bop writer will fail!")
            trimesh_objects[obj.get_cp('category_id')] = pyrender.Mesh.from_trimesh(mesh=trimesh_obj, material=material)

        _BopWriterUtility.calc_gt_masks(chunk_dirs=chunk_dirs, starting_frame_id=starting_frame_id,
                                        dataset_objects=trimesh_objects, annotation_scale=annotation_scale,
                                        delta=delta)
        _BopWriterUtility.calc_gt_info(chunk_dirs=chunk_dirs, starting_frame_id=starting_frame_id,
                                       dataset_objects=trimesh_objects, annotation_scale=annotation_scale,
                                       delta=delta)
        _BopWriterUtility.calc_gt_coco(chunk_dirs=chunk_dirs, dataset_objects=dataset_objects,
                                       starting_frame_id=starting_frame_id)
def calc_gt_masks(chunk_dirs: List[str], dataset_objects: Dict[int, pyrender.Mesh], starting_frame_id: int = 0,
                      annotation_scale: float = 1000., delta: float = 0.015):
        """ Calculates the ground truth masks.
        From the BOP toolkit (https://github.com/thodan/bop_toolkit), with the difference of using pyrender for depth
        rendering.

        :param chunk_dirs: List of directories to calculate the gt masks for.
        :param dataset_objects: Dict containing all objects to save the annotations for.
        :param starting_frame_id: The first frame id the writer has written during this run.
        :param annotation_scale: The scale factor applied to the calculated annotations (in [m]) to get them into the
                                 specified format (see `annotation_format` in `write_bop` for further details).
        :param delta: Tolerance used for estimation of the visibility masks.
        """
        # This import is done inside to avoid having the requirement that BlenderProc depends on the bop_toolkit
        # pylint: disable=import-outside-toplevel
        from bop_toolkit_lib import inout, misc, visibility
        # pylint: enable=import-outside-toplevel

        width = bpy.context.scene.render.resolution_x
        height = bpy.context.scene.render.resolution_y

        renderer = pyrender.OffscreenRenderer(viewport_width=width, viewport_height=height)

        for dir_counter, chunk_dir in enumerate(chunk_dirs):
            last_chunk_gt_fpath = os.path.join(chunk_dir, 'scene_gt.json')
            last_chunk_camera_fpath = os.path.join(chunk_dir, 'scene_camera.json')
            scene_gt = _BopWriterUtility.load_json(last_chunk_gt_fpath, keys_to_int=True)
            scene_camera = _BopWriterUtility.load_json(last_chunk_camera_fpath, keys_to_int=True)

            # Create folders for the output masks (if they do not exist yet).
            mask_dir_path = os.path.dirname(os.path.join(chunk_dir, 'mask', '000000_000000.png'))
            misc.ensure_dir(mask_dir_path)

            mask_visib_dir_path = os.path.dirname(os.path.join(chunk_dir, 'mask_visib', '000000_000000.png'))
            misc.ensure_dir(mask_visib_dir_path)

            im_ids = sorted(scene_gt.keys())

            # append to existing output
            if dir_counter == 0:
                im_ids = im_ids[starting_frame_id:]

            for im_counter, im_id in enumerate(im_ids):
                if im_counter % 100 == 0:
                    misc.log(f'Calculating GT masks - {chunk_dir}, {im_counter}')

                K = np.array(scene_camera[im_id]['cam_K']).reshape(3, 3)
                fx, fy, cx, cy = K[0, 0], K[1, 1], K[0, 2], K[1, 2]
                camera = pyrender.IntrinsicsCamera(fx=fx, fy=fy, cx=cx, cy=cy, znear=0.1, zfar=100000)

                # Load depth image.
                depth_path = os.path.join(
                    chunk_dir, 'depth', '{im_id:06d}.png').format(im_id=im_id)
                depth_im = inout.load_depth(depth_path)
                depth_im *= scene_camera[im_id]['depth_scale']  # to [mm]
                depth_im /= 1000.  # to [m]
                dist_im = misc.depth_im_to_dist_im_fast(depth_im, K)

                for gt_id, gt in enumerate(scene_gt[im_id]):
                    # create a new scene
                    scene = pyrender.Scene()

                    # add camera and current object
                    scene.add(camera)
                    t = np.array(gt['cam_t_m2c'])
                    # rescale translation depending on initial saving format
                    t /= annotation_scale

                    pose = bop_pose_to_pyrender_coordinate_system(cam_R_m2c=np.array(gt['cam_R_m2c']).reshape(3, 3),
                                                                  cam_t_m2c=t)
                    scene.add(dataset_objects[gt['obj_id']], pose=pose)

                    # Render the depth image.
                    _, depth_gt = renderer.render(scene=scene)

                    # Convert depth image to distance image.
                    dist_gt = misc.depth_im_to_dist_im_fast(depth_gt, K)

                    # Mask of the full object silhouette.
                    mask = dist_gt > 0

                    # Mask of the visible part of the object silhouette.
                    mask_visib = visibility.estimate_visib_mask_gt(
                        dist_im, dist_gt, delta, visib_mode='bop19')

                    # Save the calculated masks.
                    mask_path = os.path.join(
                        chunk_dir, 'mask', '{im_id:06d}_{gt_id:06d}.png').format(im_id=im_id, gt_id=gt_id)
                    inout.save_im(mask_path, 255 * mask.astype(np.uint8))

                    mask_visib_path = os.path.join(
                        chunk_dir, 'mask_visib',
                        '{im_id:06d}_{gt_id:06d}.png').format(im_id=im_id, gt_id=gt_id)
                    inout.save_im(mask_visib_path, 255 * mask_visib.astype(np.uint8))

4.难例渲染

手抓遮挡,纹理背景复杂

一个场景多个椰汁(【model list】又放回抽样模型)

https://github.com/DLR-RM/BlenderProc/blob/main/examples/basics/camera_sampling/README.md

物体高反光强弱灯光(明暗)物体xyz范围缩小

为了产生遮挡

注意:太小,碰撞检测会不过关,需要很多次采样,但都不一定能成功,耗时

物体重复

干扰物(自定义干扰物遮挡)

需要修改函数,传入obj和干扰物

获取obj的xyz,同时限定干扰物的xyz和obj的xyz高度接近,xy接近,z不接近,避免碰撞检测不过关

物体添加dust

指定遮挡

模糊

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C#实现身份证格式验证(自建异常实现提醒)

基本信息 中国居民身份证的格式包括18位数字,这些数字分别代表不同的信息: 第1、2位数字表示省份代码。 第3、4位数字表示城市代码。 第5、6位数字表示区县代码。 第7至14位数字表示出生年、月、日(其中7、8、9、10位是年,11、12…

整合SpringSecurity+JWT实现登录认证

一、关于 SpringSecurity 在 Spring Boot 出现之前,SpringSecurity 的使用场景是被另外一个安全管理框架 Shiro 牢牢霸占的,因为相对于 SpringSecurity 来说,SSM 中整合 Shiro 更加轻量级。Spring Boot 出现后,使这一情况情况大有…

python实战之PyQt5桌面软件

一. 演示效果 二. 准备工作 1. 使用pip 下载所需包 pyqt5 2. 下载可视化UI工具 QT Designer 链接:https://pan.baidu.com/s/1ic4S3ocEF90Y4L1GqYHPPA?pwdywct 提取码:ywct 3. 可视化UI工具汉化 把上面的链接打开, 里面有安装和汉化包, 前面的路径还要看…

基于SSM学生信息管理系统

采用技术 基于SSM学生信息管理系统的设计与实现~ 开发语言:Java 数据库:MySQL 技术:SpringMVCMyBatis 工具:IDEA/Ecilpse、Navicat、Maven 页面展示效果 总体功能设计 登录页面 后台首页 学生信息页面 添加学生用户 编辑…

Java代码混淆技术最佳实践与案例分享

摘要 本文探讨了代码混淆在保护Java代码安全性和知识产权方面的重要意义。通过混淆技术,可以有效防止代码被反编译、逆向工程或恶意篡改,提高代码的安全性。常见的Java代码混淆工具如IPAGuard、Allatori、DashO、Zelix KlassMaster和yGuard等&#xff0…

单链表算法库

singlelist.cpp #include "singlelist.h"/************************************************** ①函数名: CreatList_Head 功 能: 头插法建立单链表 参 数: (1)LinkList *&L: 传入的单链表指针地址(2)ElemType Array_used[]:要用来建表的数组(3)int Array_nu…

win 11环境配置 之 python(cmd 输入 python --version 输出为空)

当我安装好python后,在 cmd 终端输入 python 和 python --version 均无任何输出时,就知道有问题。 在 vscode 下载好 python插件后,编写demo文件,可以执行成功。 因此得出原因是 win 环境变量配置有问题 具体错误问题:…

BabySQL【2019极客大挑战】

知识点: 功能分析 登录界面一般是 where username and password 可以从username出手,注释掉and语句单引号闭合绕过 通过测试和报错信息发现是一个单引号读取输入可以单引号闭合绕过关键字过滤 or and 过滤 || &&替换双写绕过select from wher…

飞凌嵌入式即将亮相德国纽伦堡「Embedded World 2024」

2024年德国纽伦堡嵌入式展览会(Embedded World 2024)将于4月9日~4月11日盛大开幕,本届展会将展示最新的电子技术与应用,涵盖了半导体、嵌入式系统、电源、电池、测试仪器、智能制造、电子设计自动化等众多领域,并将汇集…

Aigtek:电压放大器对参数的要求是什么

电压放大器是一种用于增大输入信号幅度的电子设备,它在各种应用中发挥着重要的作用。为了确保电压放大器的性能和可靠性,对其参数有一定的要求。下面安泰电子将介绍电压放大器的几个关键参数,包括增益、带宽、输入/输出阻抗和噪声等&#xff…

Win10 搭建FTP存储服务器站点【超详细教程】

目录 第一步:打开控制面板>程序 第二步:win10左下角搜索IIS并打开 第三步:右键网站,选择添加FTP站点 第四步:添加FTP站点名称 第五步:添加IP地址和端口 第六步:身份验证与授权信息 第…

系统架构图怎么画

画架构图是架构师的一门必修功课。 对于架构图是什么这个问题,我们可以按以下等式进行概括: 架构图 架构的表达 架构在不同抽象角度和不同抽象层次的表达,这是一个自然而然的过程。 不是先有图再有业务流程、系统设计和领域模型等&#…

LLM2LLM: Boosting LLMs with Novel Iterative Data Enhancement

LLM2LLM: Boosting LLMs with Novel Iterative Data Enhancement 相关链接:arXiv GitHub 关键字:LLM、Data Augmentation、Fine-tuning、NLP、Low-data Regime 摘要 预训练的大型语言模型(LLMs)目前是解决绝大多数自然语言处理任…

助力低碳出行 | 基于ACM32 MCU的电动滑板车方案

前言 随着智能科技的快速发展,电动滑板车的驱动系统也得到了长足的发展。国内外的电动滑板车用电机驱动系统分为传统刷式电机和无刷电机两种类型。其中,传统的刷式电机已经逐渐被无刷电机所取代,无刷电机的性能和寿命都更出色,已成…

Uibot6.0 (RPA财务机器人师资培训第5天 ) 报销汇总机器人案例实战

训练网站:泓江科技 (lessonplan.cn)https://laiye.lessonplan.cn/list/ec0f5080-e1de-11ee-a1d8-3f479df4d981https://laiye.lessonplan.cn/list/ec0f5080-e1de-11ee-a1d8-3f479df4d981https://laiye.lessonplan.cn/list/ec0f5080-e1de-11ee-a1d8-3f479df4d981https…

SAP BTP云上一个JVM与DB Connection纠缠的案例

前言 最近在CF (Cloud Foundry) 云平台上遇到一个比较经典的案例。因为牵扯到JVM (app进程)与数据库连接两大块,稍有不慎,很容易引起不快。 在云环境下,有时候相互扯皮的事蛮多。如果是DB的问题,就会找DB…

day72Html

常用标签: 分类: 块级标签:独立成行 行级标签:不独立成行,同一行可放多个行级标 注意网页显示时,忽略空白字符,(回车符,空格,tab制表符) 一)块级标签&#xf…

STM32/GD32的以太网DMA描述符

继续梳理以太网的DMA描述符。 以太网DAM描述符的结构 有两种结构,链式结构和环形结构。 常用的是链式结构。 标准库中,关于DMA描述符的数据结构 以gd32f4xx_enet.c为例。 先说发送描述符。 系统分配了5个发送描述符。每个描述符对应的缓冲区大小为152…

基于双vip+GTID的半同步主从复制集群项目(MySQL集群)

项目标题:基于keepalivedGTID的半同步主从复制MySQL集群 准备七台机器,其中有四台时MySQL服务器,搭建主从复制的集群,一个master,2个slave服务器,一个延迟备份服务器。同时延迟备份服务器也可以充当异地备…

C++ 数组

一 一维数组 1 一维数组 数组名:标识这组相同的数据的名字。 数组元素:构成数组的每个数据项。 一维数组的定义 存储类型 数据类型 数组名[正整数] float score[10]; 1 定义数组时初始化数组的方法 int a[5]{12,34,56,78,9}; int a[5]{0}; int a[]{11…