Knowhow 105

obj 파일 v, vt, f 등 직접 저장하기, obj save

obj 파일은 v, vn (normal), vt(texture uv), f 등 vertex 위치와 face 구성 외에 몇가지 정보를 같이 들고 있을 수 있다. https://en.wikipedia.org/wiki/Wavefront_.obj_file Wavefront .obj file - WikipediaFrom Wikipedia, the free encyclopedia Geometry definition file format OBJ (or .OBJ) is a geometry definition file format first developed by Wavefront Technologies for its Advanced Visualizer animation package. The file format is..

Knowhow/Vision 2024.08.28

Facescape 모델 displacement map 사용법, detailed mesh 얻어내는 방법

https://facescape.nju.edu.cn/ FaceScape facescape.nju.edu.cn Face mesh 데이터셋 중 오래됐지만 여전히 많이 쓰이는 데이터 중 하나인 facescape 데이터셋. TU model이라는 이름으로 topology를 맞춰놓은 데이터가 특히 사용하기 좋다.  TU model은 근데 생각보다 해상도(mesh vertex, face 수)가 높지 않은데 데이터 자체의 용량을 줄이기 위해서 coarse와 fine을 분리해놨기 때문이다. 그냥 obj 파일에 담겨있는 mesh는 coarse 즉 vertex 수도 적고 face도 적은 기본 template mesh를 registration해둔 결과다. 그 이외 fine detail은 displacement map담겨 있다..

Knowhow/Vision 2024.08.28

Unit cube vertices, faces index (pytorch3d cube 만들기)

open3d는 다음과 같은 method가 주어져서 cube를 만드는게 뚝딱이다. cube = o3d.geometry.TriangleMesh.create_box() 아쉽게도 pytorch3d에는 이게 없어서 직접 cube의 8개 vertex와 face를 지정해준 뒤 직접 만들어야 하는데, 이게 매번 할 때마다 엄청 귀찮다. 정육면체니까 6개 face만 만들면 될 것 같지만 triangle face기 때문에 12개의 face를 만들어야 하고, 구성하는 vertex indexing 순서에 따라 normal이 뒤집힐 수도 있기 때문에 렌더링까지 잘되게 하려면 face 방향도 매번 신경써야 한다. 엄청 귀찮다... 반복 노동을 줄이기 위해 복사 붙여넣기 용으로 기록해둔다. from pytorch3d.structu..

Knowhow/Vision 2024.08.05

Torch model to ONNX model 변환 시 유의사항 (pytorch model과 ONNX 모델 결과가 다를 때)

pytorch model을 ONNX로 변환해서 사용하고자 할 때 onnx를 직접 쓸 수도 있지만 가장 편하게 쓰는 방법은 torch.onnx.export를 쓰는 방법이다.  https://pytorch.org/tutorials/advanced/super_resolution_with_onnxruntime.html (optional) Exporting a Model from PyTorch to ONNX and Running it using ONNX Runtime — PyTorch Tutorials 2.4.0+cu121 documentatNote Click here to download the full example code (optional) Exporting a Model from PyTorch to ON..

BFM face model 파라미터로 변형하기 (cropped BFM 2009 버전 예시)

https://faces.dmi.unibas.ch/bfm/index.php?nav=1-1-0&id=details MorphaceThis page is part of the old Basel Face Model from 2009, find most recent Basel Face Model here. Basel Face Model - Details Details of the Basel Face Model The geometry of the BFM consists of 53,490 3D vertices connected by 160,470 triangles. Faces of difffaces.dmi.unibas.ch BFM은 2009년 처음 만들어진 모델이지만 2017년, 2019년 총 2차례에 걸쳐 리뉴얼..

Knowhow/Vision 2024.07.30

Open3d mesh uv coordinate

이전 글 Trimesh to Open3d TriangleMesh 에서 짧게 적어두긴 했는데, open3d는 기존 graphic tool에서 쓰는 uv 좌표계랑 다르게 쓰는 특징이 있다.  OBJ가 들고 있는 UV 값이 있을 때, 이를 trimesh나 meshlab 등 각종 라이브러리나 툴에서 이를 읽을 때와 open3d로 읽을 때 방향이 반대다.  위와 같이 mesh와 uv map이 주어졌다고 보자.  trimesh.load_mesh()로 불러온 mesh와 o3d.io.read_triangle_mesh()로 불러온 mesh 내에 UV 값 자체는 똑같다.Convention trimesh나 다른 툴들은 그 값을 갖고 texture map을 읽을 때, 위와 같이 좌측 하단에 원점을 두고 UV 값을 읽는다. (..

Knowhow/Vision 2024.07.30

FLAME head model, chumpy dependency 없는 파일 만들기

https://flame.is.tue.mpg.de/ FLAME flame.is.tue.mpg.de 위 head model은 얼굴 다루면 반드시 만나는 FLAME 모델. 2017년 논문이다 보니 모델 구축이나 파라미터 최적화 같은 작업들에 필요한 auto-diff 기능들이 필요했을 때 torch보단 chumpy 라는 라이브러리를 사용했다.  이 chumpy는 python 2.0에서 만들어진 것으로 비교적 옛 버전들의 3rd party들과 dependency를 갖고 있고, 요즘 python3에서도 사용 가능하더라도 FLAME 모델 외에는 사용할 일이 pytorch 때문에 전혀 없으므로 굳이 사용할 필요가 없다.  설치조차 이제는 굳이 할 필요가 없는 옛 라이브러리가 되어버렸다.  근데 FLAME 모델 제공되..

Knowhow/Vision 2024.07.24

Open3d ray casting 쉽게 하기, 2d point to mesh intersection 찾기

camera pose, intrinsic parameter, 2d keypoint를 알고 있을 때 이를 3D mesh으로 back projection하려면 ray casting을 해야 한다. 직접 구현하려면 연산량 문제로 속도가 어마어마하게 느리기 때문에 최적화가 잘 된 기능을 가져와서 사용하는게 무조건 낫다.  우회법으로 3d mesh vertex를 projection한 뒤, 2d keypoint와 가장 가까운 vertex를 찾아내는 식으로 할 수 있겠지만, 이 방법은 vertex가 충분히 많아야 하고, mesh가 1겹일 때만 가능하다.  얼굴을 예로 들면, face keypoint와 head mesh 간의 비교 시 우회법으로 구현하면, 눈 keypoint가 뒤통수에서 나오는 경우가 있다. 당연하게도,..

Knowhow/Vision 2024.07.16

Trimesh to Open3d TriangleMesh

python에서 mesh 읽고 쓸 때, 대표적으로 사용하는 Trimesh와 open3d. 이 둘 간의 mesh 변환을 할 때 약간의 주의 사항이 있다. 단순히 vertex와 face 구성만 변환한다면 trimesh에서 as_open3d 라는 함수를 지원해주므로 간단하지만, texture까지 옮길 때는 조금 차이가 있다. def trimesh2open3d(mesh_path, texture_path): mesh = trimesh.load_mesh(mesh_path) vertices = mesh.vertices faces = mesh.faces uvs = mesh.visual.uv uvs[:,1] = 1-uvs[:,1] triangles_uvs = [] for i in range(3): triangles_uv..

Knowhow/Vision 2024.07.12