Author: byun1114

  • 영상 이미지로 mesh 만들기

    안 될때는 안 되더니, 될 때는 또 금방 된다. 이번에는 copilot이 도움이 컸다. 몇몇 부분에서 수학적인 계산이 필요한 부분이 있었는데 관련 부분을 충분히 입력하면 거의 동작 가능한 수준에서 만들어 준다.

    더 촘촘하게 mesh를 구성해보려고 했는데 2가지 이유로 안했다. 첫 번째로는 메모리 부분이다. 사소한 부분일 것 같기는 한데 numpy에서 오류가 난다. 두 번째는 현재 가로 해상도는 대략 최대 1.6mm 이다. 표면이 거칠기는 한데 그것보다는 thickness가 더 큰 영향을 미친다고 본다.

    Blender에서 불러온 다음 표면을 살짝 부드럽게 해주면 좀 더 그럴듯하다.

    콧구멍과 귓볼 처럼 굴곡이 심한 부분은 잘 안된다. 캡처 사진에서는 잘 안 보이는데 콧구멍이 5개쯤 된다.

    이 논문에서 영감을 받아서 진행했었다. 이제 저 아래쪽 그림을 보고 너무 겁먹지 않아도 좋을 듯 하다. 그 이유는 아래쪽 이미지처럼 잘 복원하려면 MRI 화질이 매우 매우 좋아야 한다. 작정하고 복원을 위한 시퀀스를 구성하지 않은 이상 짜부러진 얼굴이 나올 가능성이 높다.

  • MRI로 mesh 만들기

    기존의 알려진 방법을 기초로 시도했다.

    결론부터 말하면 기존 알고리즘으로는 아쉬운 부분이 존재한다. 제대로 만들기 위해서는 한 땀 한 땀 mesh 를 작성해야 할 필요가 있다.

    Brain MRI 중 T1 TRA SE 이미지가 적당해서 이걸로 선택했다. 한 장씩 DICOM 저장해서 확인한다. 익명성을 위해서 UUID를 이용해 버리는 바람에 DICOM에 포함된 Image Position 정보를 이용해서 순서대로 정렬시켜야 한다. Image Position 의 3번째 값이 머리-> 꼬리 방향과 연관된 정보이다.

    MRI에는 CT 처럼 HU 값이 없다. 그냥 바탕의 적당한 값을 기준으로 어두운 부분은 False 있는 부분은 True 형식으로 변환시켰다. 적절한 처리를 거치면 이렇게 얼굴의 윗 부분을 만들 수 있다.

    이 Numpy matrix에서 점에 대한 정보만 있어야 한다. Copilot에서 물어봤더니 약간 수정해야 하지만 매우 편한 스크립트를 짜주었다.

    points = []
    for x in range(blk.shape[0]):
        for y in range(blk.shape[1]):
            for z in range(blk.shape[2]):
                if blk[x, y, z] > 0:
                    points.append([x, y, z])
    
    points = numpy.array(points)

    Open3D 패키지를 이용해서 point cloud를 만들어 준다.

    pcd = open3d.geometry.PointCloud()
    pcd.points = open3d.utility.Vector3dVector(points)

    mesh 를 만들기 위해서는 법선(normal)이 있어야 한다. 당연히 이 정보는 없으니까 만들어 주어야 한다. pcd.has_normals() 을 이용해서 normal 이 있는지 알 수 있다. 없으면 estimate_normals() 을 이용하여 만들어 줄 수도 있다.

    if pcd.has_normals():
        pcd.normals = ...
    else:
        pcd.estimate_normals()

    BPA는 다음 처럼

    ## BPA
    distances = pcd.compute_nearest_neighbor_distance()
    radius = 10
    bpa_mesh = open3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(pcd, open3d.utility.DoubleVector([radius, radius * 2]))
    print(open3d.io.write_triangle_mesh("/root/3D/head_bpa.ply", bpa_mesh))

    Poisson은 다음 처럼

    poisson_mesh, densities = open3d.geometry.TriangleMesh.create_from_point_cloud_poisson(pcd, depth=9)
    bbox = pcd.get_axis_aligned_bounding_box() 
    p_mesh_crop = poisson_mesh.crop(bbox)

    이런 느낌으로 mesh를 만들 수 있다. 위에서도 언급했지만 두 방법 모두 mesh가 빠지는 부분이 있다.

  • 사생활 보호 모드

    Edge에서 Private 모드로 항상 실행하려면 다음을 추가해서 실행한다.

    -inprivate

    Firefox 라면 다음을 추가한다.

    -private-window
  • Point clouds로 Mesh 생성하기

    한 땀 한 땀 만들어야 하나 고민하고 있었는데 누군가가 이미 구현해둔 방법들이 있는 것을 알게 되었다.

    jupyterlab 환경에서는 안된 것 같다. 좀 더 확인해 볼 필요가 있다. 얼핏 검색해 본 바에 의하면 numpy 버전을 1.대로 낮추어 야 할 필요가 있는 것 같다.

    Numpy 버전을 낮추는 방법은 다시 설치를 하면 된다.

    pip install numpy==1.26.4 --break-system-packages