准化数据集在多媒体研究中至关重要。今天,我们要给大家推荐一个汇总了姿态检测数据集和渲染方法的 github repo。
项目地址:https://github.com/YoungXIAO13/ObjectPoseEstimationDatasets
这个数据集汇总了用于对象姿态估计的数据集,以及生成合成训练数据的呈现方法。在下表中,3D CAD 模型表示为模型,2D 图像表示为对象。
该项目分为四个部分:
受控环境中的对象
野外物体
3D 模型数据集
渲染方法
受控环境中的对象
此表列出了通常称为 BOP:Benchmark 6D 对象姿态估计的数据集,该数据集提供精确的 3D 对象模型和精确的 2D~3D 对齐。
可以下载所有 BOP 数据集,并使用作者提供的工具箱。
使用项目上面的代码 ply2obj.py 将原始 .ply 文件转换为 .obj 文件,并运行 create_annotation.py 为数据集中的所有场景创建一个注释文件。
以上数据集的下载地址:
HomebrewedDB:https://bop.felk.cvut.cz/datasets/
YCB-Video:https://rse-lab.cs.washington.edu/projects/posecnn/
T-LESS:https://bop.felk.cvut.cz/datasets/
Doumanoglou:https://bop.felk.cvut.cz/datasets/
Tejani:https://bop.felk.cvut.cz/datasets/
Occluded-LINEMOD:https://bop.felk.cvut.cz/datasets/
LINEMOD:https://bop.felk.cvut.cz/datasets/
野外物体
在该表中, Pix3D 和 ScanNet 提供精确的 2D-3D 对齐,而其他仅提供粗略的对齐。
PASCAL3D+ 是用于视点估计的事实基准。
ScanNet 通常用来评估场景重建和分割。
数据集下载地址:
ApolloCar3D:http://apolloscape.auto/car_instance.html
Pix3D:http://pix3d.csail.mit.edu/
ScanNet:http://www.scan-net.org/
ObjectNet3D:http://cvgl.stanford.edu/projects/objectnet3d/
PASCAL3D+:http://cvgl.stanford.edu/projects/pascal3d.html
KITTI:http://www.cvlibs.net/datasets/kitti/eval_object.php
3D 模型数据集
为了验证网络泛化能力,可以使用以下数据集生成合成训练数据。请注意,ABC 包含通用和任意的工业 CAD 型,而 ShapeNetCore 和 ModelNet 包含常见类别的对象,如汽车和椅子。
数据集地址:
ABC:https://deep-geometry.github.io/abc-dataset/
ShapeNetCore:https://www.shapenet.org/download/shapenetcore
ModelNet-40:http://modelnet.cs.princeton.edu/
渲染方法
可微渲染
这里有两篇参考论文:CVPR 2018 论文《Neural 3D Mesh Renderer》和 NIPS 2018 论文《RenderNet》。
Blender Render 渲染
本 repo 提供了相关的 python 代码,以使用 Blender 作为一个易于安装和生成照片级真实图像的 python 模块,从 3D 模型生成渲染图像。
你可以在这里找到更多关于使用它的方法。
物理模拟器
Pybullet是机器人界非常受欢迎的一个物理模拟器。
其他
Glumpy:不支持无头渲染(在 ssh 模式下会失败)
UnrealCV:Unreal Engine 4 的扩展,帮助与虚拟世界交互并与外部程序通信。
合成计算机视觉:恢复许多用于生成合成图像的技术
via:https://github.com/YoungXIAO13/ObjectPoseEstimationDatasets
雷锋网网雷锋网雷锋网
日常 Web 开发中,书写代码遵循的原则是用尽可能少的代码实现尽可能多的功能。本文将探索日常开发中遇到的需求场景,仅用一行代码来实现。
const occurrenceMap = arr => arr.reduce((acc, current) => (acc[current] = (acc[current] || 0) + 1, acc), {});
// output: { a: 2, b: 1, c: 1, d: 1 }
occurrenceMap(['a', 'b', 'c', 'a', 'd'])
const shallowClone = arr => arr.slice(0);
// or
const shallowClone = array => [...array];
// output: [ { a: 'b', b: { c: 'd' } } ]
shallowClone([{a: 'b', b: {c: 'd'}}])
由于是浅拷贝,嵌套对象或数组将通过引用拷贝,而不是复制。
const isEmptyArray = arr => Array.isArray(arr) && !arr.length;
// recommend
const isEmptyArray = ({ length }) => length === 0;
// output: true
isEmptyArray(Array(2))
({ length }) => length === 0 被大多数开发者所推荐,关于是否是数组应该再另一个函数中判断,遵循“函数单一职责原则”。
const removeDuplicates = arr => [...new Set(arr)];
// output: [ 'a', 'b' ]
removeDuplicates(['a', 'b', 'a'])
// output: [ { a: 1 }, 'b', { a: 1 } ],包含非原始值
removeDuplicates([{a: 1}, 'b', {a: 1}])
请注意:代码仅适用于具有原始值(string、number、bigint、boolean、undefined、symbol 和 null)的元素。保留元素的顺序并返回数组的副本。
const lowestNumber = arr => Math.min(...arr);
const biggestNumber = arr => Math.max(...arr);
// output: 1
lowestNumber([1, 2, 3, 1])
// output: 3
biggestNumber([1, 2, 3, 1])
const closestNumber = (arr, number) => arr.reduce((acc, current) => (Math.abs(current - number) < Math.abs(acc - number) ? current : acc) );
// output: 3
closestNumber([1, 2, 3, 4, 1], 3.2)
const indexOfLowestNumber = arr => arr.indexOf(Math.min(...arr));
const indexOfBiggestNumber = arr => arr.indexOf(Math.max(...arr));
// output: 0
indexOfLowestNumber([1, 2, 3, 4])
// output: 3
indexOfBiggestNumber([1, 2, 3, 4])
const splitInHalf = arr => [arr.slice(0, Math.ceil(arr.length / 2)), arr.slice(Math.ceil(arr.length / 2))];
// output: [[1, 2], [3, 4]]
splitInHalf([1,2,3,4])
const longestString = arr => arr.reduce((prev, curr) => prev.length > curr.length ? prev : curr);
const shortestString = arr => arr.reduce((prev, curr) => prev.length < curr.length ? prev : curr);
// output: abc
console.log(shortestString(['hello', 'fedlab', 'abc']));
// output: fedlab
console.log(longestString(['hello', 'fedlab', 'abc']));
此代码还能通过返回值的 length 属性获取到最短、最长字符串的长度。
const sum = arr => arr.reduce((a, b) => a + b, 0);
const average = arr => arr.reduce((a, b) => a + b) / arr.length
const shuffle = arr => [...arr].sort(() => 0.5 - Math.random());
const toCamelCase = str => str.replace(/[\s\._-]+\w/g, (m) => m[m.length-1].toUpperCase());
// output: helloWorld
toCamelCase('hello-world')
toCamelCase('hello world')
toCamelCase('hello_world')
toCamelCase('hello.world')
const toPascalCase = str => str.replace(/[\s\._-]+\w/g, (m) => m[m.length - 1].toUpperCase()).replace(str.charAt(0), str.charAt(0).toUpperCase());
// output: HelloWorld
toPascalCase('hello-world')
toPascalCase('hello world')
toPascalCase('hello_world')
toPascalCase('hello.world')
const htmlSpecialChars = str => str.replace(/[&"'<>]/g, (i) => ({ "&": "&", '"': """, "'": "'", "<": "<", ">": ">" }[i]));
const reverseWords = (str) => str.replace(/(\p{L}+)/gu, (word) => [...word].reverse().join(''));
// output: olleh dlrow
reverseWords('hello world')
Unicode标准定义了每个字符的性质,许多支持Unicode的程序能够通过\p{quality}来支持其中的一部分。
const reverseString = str => [...str].reverse().join("");
const truncateAfterWord = (str, chars, placeholder = '…') => str.length < chars ? str : `${str.substr( 0, str.substr(0, chars - placeholder.length).lastIndexOf(" "))}${placeholder}`
// output: foo bar…
truncateAfterWord('foo bar baz', 9)
520 表白可以用一下子哈。
const readline=require("readline");function genMonospacedAlphabet(e){return{" ":" ",a:"a",b:"b",c:"c",d:"d",e:"e",f:"f",g:"g",h:"h",i:"i",j:"j",k:"k",l:"l",m:"m",n:"n",o:"o",p:"p",q:"q",r:"r",s:"s",t:"t",u:"u",v:"v",w:"w",x:"x",y:"y",z:"z",A:"A",B:"B",C:"C",D:"D",E:"E",F:"F",G:"G",H:"H",I:"I",J:"J",K:"K",L:"L",M:"M",N:"N",O:"O",P:"P",Q:"Q",R:"R",S:"S",T:"T",U:"U",V:"V",W:"W",X:"X",Y:"Y",Z:"Z","!":"!","@":"@","#":"#",$:"$","%":"%","^":"^","&":"&","*":"*","(":"(",")":")",_:"_","+":"+"}[e]}const rl=readline.createInterface({input:process.stdin,output:process.stdout});rl.question("Say something: ",(e=>{rl.close();const t=e.split("").map((e=>genMonospacedAlphabet(e))).join(""),s=Math.pow,n=e=>new Promise((t=>{setTimeout((()=>{t()}),e)})),o=genMonospacedAlphabet(" "),a=(()=>{let e=-1,s=t.length;return()=>(e>s-1?e=0:e++,e===s||/\s/.test(t[e])?o:t[e])})(),r=async(e,t)=>{await process.stdout.write(((e,t,n=1,o=1)=>s(s(e*n*.05,2)+s(-t*o*.1,2)-1,3)-s(e*n*.05,2)*s(-t*o*.1,3)<0)(e,t,1.2)?"[91m"+a():o)};let i=-15;const c=async()=>{for(let e=-25;e<25;e+=1)await r(e,i),await n(2);process.stdout.write("\n"),i<10&&(i++,c())};c()}));
以上就是我们开发中经常遇到的场景,都可以用一行代码来实现。如果你还有其他的 一行代码实现的逆天操作 欢迎留言讨论。
先看看这哥俩的好处。让我们一起来学习Free Pascal和Lazarus。
下面是基本步骤和资源,能够帮助你开启学习之旅:
program HelloWorld;
begin
writeln('Hello, World!');
end.
全文结束。下期预告:构建一个简单的GUI应用程序
#编程#
*请认真填写需求信息,我们会在24小时内与您取得联系。