Проблема с использованием оптимизации Ллойда и Mesh_domain :: create_labeled_image_mesh_domain - PullRequest
0 голосов
/ 21 мая 2019

Я использую CGAL 4.13 (Linux Fedora 29) для создания трехмерных сеток из сегментированных анатомических изображений. Я хотел бы использовать оптимизацию Ллойда, но я получил воспроизводимым образом ошибку времени выполнения.

Чтобы проиллюстрировать мою проблему, я изменил пример mesh_3D_image.cpp , добавив шаг оптимизации Lloyd, как показано ниже. Программа компилируется без сообщения об ошибке / предупреждения.

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>

#include <CGAL/Mesh_triangulation_3.h>
#include <CGAL/Mesh_complex_3_in_triangulation_3.h>
#include <CGAL/Mesh_criteria_3.h> 

#include <CGAL/Labeled_mesh_domain_3.h>
#include <CGAL/make_mesh_3.h>
#include <CGAL/Image_3.h>

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Labeled_mesh_domain_3<K> Mesh_domain;

typedef CGAL::Sequential_tag Concurrency_tag;

typedef CGAL::Mesh_triangulation_3<Mesh_domain,CGAL::Default,Concurrency_tag>::type Tr;
typedef CGAL::Mesh_complex_3_in_triangulation_3<Tr> C3t3;
typedef CGAL::Mesh_criteria_3<Tr> Mesh_criteria; 

using namespace CGAL::parameters;

int main(int argc, char* argv[])
{
  const char* fname = (argc>1)?argv[1]:"data/liver.inr.gz";
  CGAL::Image_3 image;
  if(!image.read(fname)){
    std::cerr << "Error: Cannot read file " <<  fname << std::endl;
    return EXIT_FAILURE;
  }
  Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image);
  Mesh_criteria criteria(facet_angle=30, facet_size=6, facet_distance=4,
                     cell_radius_edge_ratio=3, cell_size=8);

  C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria);

  // !!! THE FOLLOWING LINE MAKES THE PROGRAM CRASH !!!
  CGAL::lloyd_optimize_mesh_3(c3t3, domain, time_limit=30); 

  std::ofstream medit_file("out.mesh");
  c3t3.output_to_medit(medit_file); 

  return 0;
}

Я компилирую его, используя следующий CMakeLists.txt файл:

# Created by the script cgal_create_CMakeLists

project( executables )
cmake_minimum_required(VERSION 2.8.11)
find_package( CGAL QUIET COMPONENTS  )

# !!! I had to add manually the following line !!!    
find_package(CGAL COMPONENTS ImageIO)

include( ${CGAL_USE_FILE} )
find_package( Boost REQUIRED )
add_executable( executables  lloyd.cpp )
add_to_cached_list( CGAL_EXECUTABLE_TARGETS executables )    
target_link_libraries(executables   ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} )

Сетка не создается. Я получаю следующее сообщение:

$ ./build/mesh_3D_image завершение вызова после выброса экземпляра CGAL :: Precondition_exception what (): ОШИБКА CGAL: нарушение предварительного условия! Expr: std :: distance (первая, последняя)> = 3 Файл: /usr/include/CGAL/Mesh_3/Lloyd_move.h Линия: 419 Прервано (ядро сброшено)

Где мой код неправильный, и как я могу вызвать оптимизацию для сеток, созданных 3D-изображениями?

Ответы [ 2 ]

1 голос
/ 06 июня 2019

на самом деле, когда CGAL::make_mesh_3() называется так:

C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria);

внутренне запускает CGAL::perturb_mesh_3() и CGAL::exude_mesh_3(). Последнее меняет вес вершин в регулярной триангуляции и всегда должно называться последним (см. Предупреждение в документации CGAL :: exude_mesh_3 () .

Единственное ограничение в заказе - то, что exuder должен быть вызван последним. Так что вы можете позвонить

C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria, lloyd(time_limit=30));

или

C3t3 c3t3 = CGAL::make_mesh_3<C3t3>(domain, criteria, no_exude());
CGAL::lloyd_optimize_mesh_3(c3t3, domain, time_limit = 30);
CGAL::exude_mesh_3(c3t3);
0 голосов
/ 21 мая 2019

Вы удалили часть:

  if(!image.read(fname)){
    std::cerr << "Error: Cannot read file " <<  fname << std::endl;
    return EXIT_FAILURE;
  }

из примера, которая фактически читает изображение из файла.

...