Using ShapeWorks as a library
ShapeWorks can be used as a library, for example as part of an ITK based application. To do so, when building ShapeWorks, specify CMAKE_INSTALL_PREFIX and use make install:
$ ccmake -DCMAKE_INSTALL_PREFIX=</path/to/sw/install>
$ make install
An example using ShapeWorks as a library in an ITK application is given in Examples/C++
CMakeLists.txt:
``` cmake_minimum_required(VERSION 3.10.2)
project(HelloShapeWorksItk)
set(CMAKE_CXX_STANDARD 17)
Find ShapeWorks
find_package(ShapeWorks REQUIRED)
SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--disable-new-dtags")
Find ITK
find_package(ITK REQUIRED)
include(${ITK_USE_FILE})
add_executable(HelloShapeWorksItk HelloShapeWorksItk.cpp)
target_link_libraries(HelloShapeWorksItk ${ITK_LIBRARIES} shapeworks::Optimize shapeworks::Groom shapeworks::Analyze pybind11::embed ) ```
HelloShapeWorksItk.cpp: ```
include
// itk includes
include "itkImage.h"
include "itkMesh.h"
include "itkRegularSphereMeshSource.h"
include "itkMeshFileWriter.h"
include "itkMeshIOFactory.h"
include "itkVTKPolyDataMeshIOFactory.h"
// shapeworks includes
include
include
include
include
include
constexpr unsigned int Dimension = 3;
using TCoordinate = float;
using TMesh = itk::Mesh
void create_sphere(double radius, std::string name) { // Create the sphere source. auto sphere = TSphere::New();
TSphere::VectorType scale; scale.Fill( radius ); sphere->SetScale( scale ); sphere->SetResolution( 5 ); sphere->Update();
// We now assign it to a mesh pointer. TMesh::Pointer mesh = sphere->GetOutput();
// It is necessary to disconnect the mesh from the pipeline; // otherwise, the point and cell data will be deallocated // when we call "Update()" on the writer later in the program. mesh->DisconnectPipeline();
auto mesh_writer = TMeshWriter::New(); mesh_writer->SetFileName(name); mesh_writer->SetInput(mesh); mesh_writer->Update(); }
int main() {
itk::VTKPolyDataMeshIOFactory::RegisterOneFactory(); // auto registeredIOs = itk::ObjectFactoryBase::CreateAllInstance( "itkMeshIOBase" );
typedef itk::Image< unsigned short, 3 > ImageType; ImageType::Pointer image = ImageType::New();
std::cout << "Hello ShapeWorks ITK World!" << std::endl;
// create a ShapeWorks Project
auto project = std::make_shared
std::cout << "Step 1: Use ITK to generate input data\n";
for (int i=5;i<9;i++) {
auto filename = "mesh" + std::to_string(i) + ".vtk";
std::cout << "Creating input file: " << filename << "\n";
create_sphere(i, filename);
auto subject = std::make_shared
// groom the inputs std::cout << "Step 2: Groom Inputs\n"; shapeworks::Groom groom{project}; groom.run();
// create a ShapeWorks Optimizer std::cout << "Step 3: Creating Shape Model\n"; shapeworks::Optimize optimize; shapeworks::OptimizeParameters params(project); params.set_up_optimize(&optimize); optimize.SetProject(project);
// run the optimizer bool success = optimize.Run(); project->save("HelloShapeWorksItk.swproj");
// perform analysis std::cout << "Step 4: Analyze\n"; shapeworks::Analyze analyze{project}; analyze.run_offline_analysis("analysis.json");
return 0; } ```
Configure using -DShapeWorks_DIR and the prefix module path used for building ShapeWorks. For example:
cd /path/to/shapeworks/Examples/C++
mkdir build
cd build
cmake .. -DShapeWorks_DIR=</path/to/sw/install>/lib/cmake/ShapeWorks -DCMAKE_PREFIX_PATH=</path/to/shapeworks/dependencies/install>
Build:
make
Run:
./HelloShapeWorksItk
Output:
Hello ShapeWorks ITK World!
Step 1: Use ITK to generate input data
Creating input file: mesh5.vtk
Creating input file: mesh6.vtk
Creating input file: mesh7.vtk
Creating input file: mesh8.vtk
Step 2: Groom Inputs
Step 3: Creating Shape Model
ShapeWorks: TBB using 16 threads
Verbosity 0: This will be the only output on your screen, unless there are any errors. Increase the verbosity if needed.
Step 4: Analyze
[2022-10-02 23:31:39.663] [info] ShapeWorks Offline Analysis
[2022-10-02 23:31:39.663] [info] number of subjects: 4
[2022-10-02 23:31:39.665] [info] Computing stats...
[2022-10-02 23:31:39.665] [info] Computed stats successfully
[2022-10-02 23:31:39.665] [info] number of modes: 3
[2022-10-02 23:31:39.676] [info] eigen value [0]: 213.72417259473602
[2022-10-02 23:31:39.676] [info] explained_variance [0]: 99.12
[2022-10-02 23:31:39.676] [info] cumulative_explained_variance [0]: 99.12
[2022-10-02 23:31:39.793] [info] eigen value [1]: 1.8944878261819007
[2022-10-02 23:31:39.793] [info] explained_variance [1]: 0.88
[2022-10-02 23:31:39.793] [info] cumulative_explained_variance [1]: 100.00
[2022-10-02 23:31:39.902] [info] eigen value [2]: 0.0016418139547566765
[2022-10-02 23:31:39.902] [info] explained_variance [2]: 0.00
[2022-10-02 23:31:39.902] [info] cumulative_explained_variance [2]: 100.00