Knowhow/Vision 46

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

Opencv imread/imwrite vs PIL open/save speed 및 memory 비교

이미지 파일을 읽을 때 opencv 혹은 PIL을 쓴다. 두 라이브러리의 기능적 차이는 없다만 경험적으로 보면 읽는 속도와 쓰는 속도가 다름을 알 수 있다. 상황에 따라서 opencv가 효율적일 때도, PIL이 효율적일 때도 있는데 각각 어떤 상황인지 파악해두었다. 왜 차이가 발생하는지 알 수 있는 경우는 이유도 같이 적는다. 이미지 읽기확장자가 PNG일 때 : opencv 써야 빠르다.cv2.imread/imwrite가 훨씬 빠르다. meta 정보를 포함한 DSLR 12MB 이미지의 경우, 10초 가량 차이가 날 때도 있다. 차이가 적을 땐 적지만 클 땐 10배도 난다. 웬만하면 opencv로 png 읽자.확장자가 JPG일 때 : PIL 써야 빠르다.Image.open으로 읽는 것이 약 2배 빠르다. ..

Knowhow/Vision 2024.06.22

COCO bounding box format, scale factor

COCO bounding box format은 document를 보면 (x,y,w,h)을 따른다고 적혀있다. 순서대로 사각형의 left top (x, y) 값과 사각형의 (width, height)라는 뜻이다.  그런데 실제로 보면 값이 다음과 같이 0~1 값으로 normalize 되어있는 것을 볼 수 있다.45 0.479492 0.688771 0.955609 0.595545 0.736516 0.247188 0.498875 0.47641750 0.637063 0.732938 0.494125 0.51058345 0.339438 0.418896 0.678875 0.781549 0.646836 0.132552 0.118047 0.096937549 0.773148 0.129802 0.0907344 0.09722..

Knowhow/Vision 2024.04.25

Double sphere 모델 projection-failed region

광각 카메라 모델 중 double sphere 모델을 보면 수식 상 다음과 같이 projection이 실패하는 조건이 있다. 여기서 저 수식 (43)이 의미하는 범위가 대충 지금 광각 카메라가 표현할 수 있는 화각 범위 밖이라는 느낌은 오는데 정확히 어떤 형태인지가 궁금했다. 내가 캘리브레이션했었던 double sphere 모델 주변에 point를 채우고 수식(43) 조건에 필터링되는 point만 남기면 다음 그림과 같다.예상했던 것과 같이 카메라 뒤로 원뿔 형태로 퍼지는 영역이 잡힌다. 광각 이미지가 동심원을 그리듯 표현되어 있고 렌즈도 원이기 때문에 projection-failed 영역은 원뿔 모양이었다. invalid projection 을 그냥 무시하고 구현을 해왔었는데 영역을 보니... 무조건 ..

Knowhow/Vision 2024.02.28

Fisheye 카메라 모델도 solvePnP 이용해서 자세 초기화/추정하는 방법

카메라 자세를 초기화할 때 가장 많이 쓰이는 방법이 PnP를 사용하는 것이다. 이미 알고 있는 3D point set과 이미지에서 검출한 2D point set이 있을 경우, 수학적으로 자세를 아주 간단하게 구할 수 있고 심지어 opencv 함수로 구현되어 있기 때문에 단 한 줄이면 카메라 자세 값을 계산할 수 있다. 하지만 카메라가 광각 카메라여서 pinhole model로 표현이 안될 경우에는 이러한 접근이 어렵다. PnP 알고리즘은 3D point와 2D point 간의 관계가 서로 linear projection일 경우를 가정하기 때문이다. 다른 말로 표현하면 빛이 직진해서 바로 이미지로 맺혔을 경우에만 적용이 가능하다. 반면 광각 카메라 (특히 180도가 넘어가는) 의 경우, 2D point와 ..

Knowhow/Vision 2024.02.28