diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4148520e7b8adaa51f7cbadae02f828cf22e8174..856769139da280892e1a01d99cf4f83dd60fee13 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -22,14 +22,12 @@ find_package(Eigen3 3.3 REQUIRED NO_MODULE)
 # make cache variables for install destinations
 include(GNUInstallDirs)
 
-if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
-    if (DEFINED ENV{CONDA_PREFIX})
-        set(CMAKE_INSTALL_LIBDIR "lib")
-        set(CMAKE_INSTALL_PREFIX "$ENV{CONDA_PREFIX}")
-    else()
-        set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/install")
-    endif()
-endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+if (DEFINED ENV{CONDA_PREFIX})
+    set(CMAKE_INSTALL_LIBDIR "lib")
+    set(CMAKE_INSTALL_PREFIX "$ENV{CONDA_PREFIX}")
+else()
+    set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/install")
+endif()
 
 add_subdirectory(cpp)
 add_subdirectory(wrp)
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index 8c0ddac3188a98b2f07ba00cf63518ed31b4a785..80a241c95734744182ac0ba8b04006b6ab289514 100644
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -1,9 +1,12 @@
 project(_cpp)
 
 add_library(_cpp SHARED
+    CgalLabelledImage.h
     LabelledTetrahedralMesh.h
+    CgalLabelledImage.cpp
     LabelledTetrahedralMesh.cpp
 )
 target_link_libraries(_cpp PUBLIC Eigen3::Eigen)
+target_link_libraries(_cpp PUBLIC CGAL::CGAL)
 
 install(TARGETS _cpp DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
\ No newline at end of file
diff --git a/cpp/CgalLabelledImage.cpp b/cpp/CgalLabelledImage.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ed754bac786d5353dbf01dd049109c36f9425392
--- /dev/null
+++ b/cpp/CgalLabelledImage.cpp
@@ -0,0 +1,25 @@
+#include <iostream>
+
+#include "CgalLabelledImage.h"
+
+
+CGAL::Image_3 buildCgalImage(Eigen::Array<unsigned short, Eigen::Dynamic, 1> image_array, Eigen::Array<int, 3, 1> shape, Eigen::Array<double, 3, 1> voxelsize)
+{
+    _image* image = _createImage(
+        shape(0), shape(1), shape(2), 1,
+        voxelsize(0), voxelsize(1), voxelsize(2), 2,
+        WK_FIXED, SGN_UNSIGNED
+    );
+
+    auto it = image_array.begin();
+    for (int x=0; x<shape(0); x++) {
+        for (int y=0; y<shape(1); y++) {
+            for (int z=0; z<shape(2); z++) {
+                CGAL::IMAGEIO::static_evaluate<unsigned short>(image, x, y, z) = *it;
+                ++it;
+            }
+        }
+    }
+
+    return CGAL::Image_3(image);
+}
diff --git a/cpp/CgalLabelledImage.h b/cpp/CgalLabelledImage.h
new file mode 100644
index 0000000000000000000000000000000000000000..ba288125b6cc28bddac3b9ca0f3637b9de98f7d6
--- /dev/null
+++ b/cpp/CgalLabelledImage.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include <CGAL/Image_3.h>
+
+#include <Eigen/Dense>
+
+
+CGAL::Image_3 buildCgalImage(Eigen::Array<unsigned short, Eigen::Dynamic, 1> image_array, Eigen::Array<int, 3, 1> shape, Eigen::Array<double, 3, 1> voxelsize={1.0, 1.0, 1.0});
\ No newline at end of file
diff --git a/src/pybind_example/labelled_tetrahedral_mesh.py b/src/pybind_example/labelled_tetrahedral_mesh.py
index 7014b328d75f16f644535a5b3496a64e10863848..4699c0f0ec24f4d76310cb5c72baf992000b14ed 100644
--- a/src/pybind_example/labelled_tetrahedral_mesh.py
+++ b/src/pybind_example/labelled_tetrahedral_mesh.py
@@ -1 +1,10 @@
-from ._wrp import LabelledTetrahedralMesh, make_tetrahedron
\ No newline at end of file
+from typing import Iterable, Optional
+
+import numpy as np
+
+from ._wrp import LabelledTetrahedralMesh, make_tetrahedron
+from ._wrp import build_cgal_image as _build_cgal_image
+
+
+def build_cgal_image(img: np.ndarray, voxelsize: Optional[Iterable[float]]=(1., 1., 1.)) -> bool:
+    return _build_cgal_image(img.ravel().astype(np.uint16), img.shape, voxelsize)
diff --git a/tests/test_cgal_image.py b/tests/test_cgal_image.py
new file mode 100644
index 0000000000000000000000000000000000000000..9506048491d2ef6b7bd1eda014fdbed76da616fb
--- /dev/null
+++ b/tests/test_cgal_image.py
@@ -0,0 +1,23 @@
+import unittest
+
+import numpy as np
+
+from pybind_example.labelled_tetrahedral_mesh import build_cgal_image
+
+
+class TestCgalImage(unittest.TestCase):
+
+    def setUp(self):
+        self.image = np.zeros((10, 8, 6), dtype=np.uint16)
+        self.image[:, :, 4:] = 1
+        self.image[:, :4, :4] = 2
+        self.image[:, 4:, :4] = 3
+
+        self.voxelsize = [0.5, 0.5, 1]
+
+    def tearDown(self):
+        pass
+
+    def test_cgal_image(self):
+        res = build_cgal_image(self.image, voxelsize=self.voxelsize)
+        assert res == 0
diff --git a/wrp/LabelledTetrahedralMeshWrapper.cpp b/wrp/LabelledTetrahedralMeshWrapper.cpp
index 8fcc884ecf74ee2dc0adc1f19ac7aa2e41bdc846..744befaa7970b07c328b7915dc0e43d36e27d1f4 100644
--- a/wrp/LabelledTetrahedralMeshWrapper.cpp
+++ b/wrp/LabelledTetrahedralMeshWrapper.cpp
@@ -2,10 +2,21 @@
 #include <pybind11/stl.h> // This header is needed to work with STL containers like std::vector
 #include <pybind11/eigen.h>
 
+#include "CgalLabelledImage.h"
 #include "LabelledTetrahedralMesh.h"
 
 namespace py = pybind11;
 
+
+int cgalLabelledImage(Eigen::Array<unsigned short, Eigen::Dynamic, 1> image_array, Eigen::Array<int, 3, 1> shape, Eigen::Array<double, 3, 1> voxelsize)
+{
+    CGAL::Image_3 image = buildCgalImage(image_array, shape, voxelsize);
+    if ((image.xdim() != shape(0)) || (image.ydim() != shape(1)) || (image.zdim() != shape(2))) {
+        return EXIT_FAILURE;
+    }
+    return 0;
+}
+
 PYBIND11_MODULE(_wrp, m) {
     py::class_<LabelledTetrahedralMesh>(m, "LabelledTetrahedralMesh")
         .def(py::init<>())
@@ -16,4 +27,6 @@ PYBIND11_MODULE(_wrp, m) {
         .def("add_tetra", &LabelledTetrahedralMesh::addTetra, py::arg("tetra"), py::arg("label"));
 
     m.def("make_tetrahedron", &makeTetrahedron);
+
+    m.def("build_cgal_image", &cgalLabelledImage, py::arg("image_array"), py::arg("shape"), py::arg("voxelsize"));
 }
\ No newline at end of file