diff --git a/CMakeExternals/Vigra.cmake b/CMakeExternals/Vigra.cmake index 80e0fd99ee..f79b5ff82c 100644 --- a/CMakeExternals/Vigra.cmake +++ b/CMakeExternals/Vigra.cmake @@ -1,65 +1,72 @@ #----------------------------------------------------------------------------- # VIGRA #----------------------------------------------------------------------------- if(MITK_USE_Vigra) # Sanity checks if(DEFINED Vigra_DIR AND NOT EXISTS ${Vigra_DIR}) message(FATAL_ERROR "Vigra_DIR variable is defined but corresponds to non-existing directory") endif() if(NOT ${MITK_USE_HDF5}) message(FATAL_ERROR "HDF5 is required for Vigra. Please enable it.") endif() set(proj Vigra) set(proj_DEPENDENCIES HDF5) set(Vigra_DEPENDS ${proj}) # If a mac ports installation is present some imaging-io-libraries may interfere with the vigra build. # Hence, we exclude them here. set(mac_additional_cmake_args) if(APPLE) - set(mac_additional_cmake_args -DJPEG_INCLUDE_DIR= -DJPEG_LIBRARY= -DTIFF_INCLUDE_DIR= -DTIFF_LIBRARY= -DPNG_LIBRARY_RELEASE= -DPNG_PNG_INCLUDE_DIR= ) + set(mac_additional_cmake_args + -DJPEG_INCLUDE_DIR= + -DJPEG_LIBRARY= + -DTIFF_INCLUDE_DIR= + -DTIFF_LIBRARY= + -DPNG_LIBRARY_RELEASE= + -DPNG_PNG_INCLUDE_DIR= + ) endif() if(NOT DEFINED Vigra_DIR) set(additional_cmake_args ) if(CTEST_USE_LAUNCHERS) list(APPEND additional_cmake_args "-DCMAKE_PROJECT_${proj}_INCLUDE:FILEPATH=${CMAKE_ROOT}/Modules/CTestUseLaunchers.cmake" ) endif() ExternalProject_Add(${proj} URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/vigra-1.10.0-src.tar.gz URL_MD5 4f963f0be4fcb8b06271c2aa40baa9be PATCH_COMMAND ${PATCH_COMMAND} -N -p1 -i ${CMAKE_CURRENT_LIST_DIR}/Vigra.patch CMAKE_GENERATOR ${gen} CMAKE_GENERATOR_PLATFORM ${gen_platform} CMAKE_ARGS ${ep_common_args} ${additional_cmake_args} ${mac_additional_cmake_args} -DAUTOEXEC_TESTS:BOOL=OFF -DWITH_VIGRANUMPY:BOOL=OFF -DHDF5_DIR:PATH=${HDF5_DIR} -DCMAKE_INSTALL_RPATH_USE_LINK_PATH:BOOL=TRUE -DCMAKE_INSTALL_PREFIX:PATH= CMAKE_CACHE_ARGS ${ep_common_cache_args} CMAKE_CACHE_DEFAULT_ARGS ${ep_common_cache_default_args} DEPENDS ${proj_DEPENDENCIES} ) set(Vigra_DIR ${ep_prefix}) else() mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") endif() endif(MITK_USE_Vigra) diff --git a/CMakeExternals/Vigra.patch b/CMakeExternals/Vigra.patch index bac3758ab4..8002ed96bb 100644 --- a/CMakeExternals/Vigra.patch +++ b/CMakeExternals/Vigra.patch @@ -1,479 +1,519 @@ diff -urNb vigra-Version-1-10-0/CMakeLists.txt Vigra/CMakeLists.txt --- vigra-Version-1-10-0/CMakeLists.txt 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/CMakeLists.txt 2015-03-03 10:13:57.693725000 +0100 @@ -70,7 +70,12 @@ IF(WITH_OPENEXR) ENDIF() IF(WITH_HDF5) + FIND_PACKAGE(HDF5 PATHS ${HDF5_DIR} PATH_SUFFIXES hdf5 NO_DEFAULT_PATH NO_MODULE) + IF(NOT HDF5_FOUND) VIGRA_FIND_PACKAGE(HDF5) + ENDIF() + # HDF5 changed their config, this ports the new style to the old style + set(HDF5_LIBRARIES ${HDF5_EXPORT_LIBRARIES}) ENDIF() IF(WITH_BOOST_GRAPH) @@ -395,3 +398,4 @@ ENDIF() MESSAGE( STATUS "---------------------------------------------------------" ) + diff -urNb vigra-Version-1-10-0/config/VigraConfig.cmake.in Vigra/config/VigraConfig.cmake.in --- vigra-Version-1-10-0/config/VigraConfig.cmake.in 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/config/VigraConfig.cmake.in 2015-03-03 10:13:57.693725000 +0100 @@ -1,7 +1,9 @@ get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) get_filename_component(Vigra_TOP_DIR "${SELF_DIR}/../../" ABSOLUTE) -include(${SELF_DIR}/vigra-targets.cmake) +if(NOT TARGET vigraimpex) + include(${SELF_DIR}/vigra-targets.cmake) +endif() get_target_property(VIGRA_TYPE vigraimpex TYPE) if(${VIGRA_TYPE} STREQUAL "STATIC_LIBRARY") SET(VIGRA_STATIC_LIB True) @@ -12,3 +14,4 @@ IF(EXISTS ${SELF_DIR}/../vigranumpy/VigranumpyConfig.cmake) INCLUDE(${SELF_DIR}/../vigranumpy/VigranumpyConfig.cmake) ENDIF() + diff -urNb vigra-Version-1-10-0/include/vigra/random_forest/rf_common.hxx Vigra/include/vigra/random_forest/rf_common.hxx --- vigra-Version-1-10-0/include/vigra/random_forest/rf_common.hxx 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/include/vigra/random_forest/rf_common.hxx 2015-07-08 18:55:16.000000000 +0200 @@ -558,6 +558,7 @@ int is_weighted_; // class_weights_ are used double precision_; // termination criterion for regression loss int response_size_; + int max_tree_depth; template void to_classlabel(int index, T & out) const @@ -583,7 +584,8 @@ EQUALS(class_weights_), EQUALS(is_weighted_), EQUALS(precision_), - EQUALS(response_size_) + EQUALS(response_size_), + EQUALS(max_tree_depth) { std::back_insert_iterator > iter(classes); @@ -604,7 +606,8 @@ EQUALS(class_weights_), EQUALS(is_weighted_), EQUALS(precision_), - EQUALS(response_size_) + EQUALS(response_size_), + EQUALS(max_tree_depth) { std::back_insert_iterator > iter(classes); @@ -624,7 +627,8 @@ EQUALS(used_); EQUALS(is_weighted_); EQUALS(precision_); - EQUALS(response_size_) + EQUALS(response_size_); + EQUALS(max_tree_depth) class_weights_.clear(); std::back_insert_iterator > iter2(class_weights_); @@ -648,7 +652,8 @@ EQUALS(used_); EQUALS(is_weighted_); EQUALS(precision_); - EQUALS(response_size_) + EQUALS(response_size_); + EQUALS(max_tree_depth) class_weights_.clear(); std::back_insert_iterator > iter2(class_weights_); @@ -677,7 +682,8 @@ COMPARE(used_); COMPARE(class_weights_); COMPARE(classes); - COMPARE(response_size_) + COMPARE(response_size_); + COMPARE(max_tree_depth) #undef COMPARE return result; } @@ -715,6 +721,7 @@ PULL(used_, int); PULL(precision_, double); PULL(response_size_, int); + PULL(max_tree_depth, int); if(is_weighted_) { vigra_precondition(end - begin == 10 + 2*class_count_, @@ -747,6 +754,7 @@ PUSH(used_); PUSH(precision_); PUSH(response_size_); + PUSH(max_tree_depth); if(is_weighted_) { std::copy(class_weights_.begin(), @@ -773,6 +781,7 @@ PULL(used_, int); PULL(precision_, double); PULL(response_size_, int); + PULL(max_tree_depth, int); class_weights_ = in["class_weights_"]; #undef PUSH } @@ -789,6 +798,7 @@ PUSH(used_); PUSH(precision_); PUSH(response_size_); + PUSH(max_tree_depth); in["class_weights_"] = class_weights_; #undef PUSH } @@ -805,7 +815,8 @@ used_(false), is_weighted_(false), precision_(0.0), - response_size_(1) + response_size_(1), + max_tree_depth(50) {} @@ -857,7 +868,7 @@ is_weighted_ = false; precision_ = 0.0; response_size_ = 0; - + max_tree_depth = 50; } bool used() const diff -urNb vigra-Version-1-10-0/include/vigra/random_forest/rf_decisionTree.hxx Vigra/include/vigra/random_forest/rf_decisionTree.hxx --- vigra-Version-1-10-0/include/vigra/random_forest/rf_decisionTree.hxx 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/include/vigra/random_forest/rf_decisionTree.hxx 2015-07-08 18:55:16.000000000 +0200 @@ -90,6 +90,8 @@ ProblemSpec<> ext_param_; unsigned int classCount_; + std::map m_Parents; + public: /* \brief Create tree with parameters */ @@ -350,6 +352,22 @@ continueLearn(features,labels,stack_entry,split,stop,visitor,randint); } +template < class TRandomForest> +int GetTreeDepthForNode(int nodeIndex, TRandomForest* rf) +{ + int depth = 0; + while (true) + { + if (nodeIndex < 1) + { + break; + } + ++depth; + nodeIndex = rf->m_Parents[nodeIndex]; + } + return depth; +} + template < class U, class C, class U2, class C2, class StackEntry_t, @@ -374,6 +392,11 @@ size_t last_node_pos = 0; StackEntry_t top=stack.back(); + Split_t* splitPointer = &split; + bool isDepthSplitter = true; + + int maximumTreeDepth = splitPointer->GetMaximumTreeDepth(); + while(!stack.empty()) { @@ -392,7 +415,20 @@ //kind of node to make TreeInt NodeID; - if(stop(top)) + bool depthStop = false; + if (isDepthSplitter) + { + int currentDepthLevel; + if (top.leftParent != StackEntry_t::DecisionTreeNoParent) + currentDepthLevel = GetTreeDepthForNode(top.leftParent, this); + else + currentDepthLevel = GetTreeDepthForNode(top.rightParent, this); + + depthStop = (currentDepthLevel >= maximumTreeDepth); + } + if(stop(top) || (depthStop)) + + //if (stop(top) || currentDepthLevel >= MaximumSplitDepth(split)) NodeID = split.makeTerminalNode(features, labels, top, @@ -421,17 +457,20 @@ // Using InteriorNodeBase because exact parameter form not needed. // look at the Node base before getting scared. last_node_pos = topology_.size(); + m_Parents[last_node_pos] = StackEntry_t::DecisionTreeNoParent; if(top.leftParent != StackEntry_t::DecisionTreeNoParent) { NodeBase(topology_, parameters_, top.leftParent).child(0) = last_node_pos; + m_Parents[last_node_pos] = top.leftParent; } else if(top.rightParent != StackEntry_t::DecisionTreeNoParent) { NodeBase(topology_, parameters_, top.rightParent).child(1) = last_node_pos; + m_Parents[last_node_pos] = top.rightParent; } diff -urNb vigra-Version-1-10-0/include/vigra/random_forest/rf_nodeproxy.hxx Vigra/include/vigra/random_forest/rf_nodeproxy.hxx --- vigra-Version-1-10-0/include/vigra/random_forest/rf_nodeproxy.hxx 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/include/vigra/random_forest/rf_nodeproxy.hxx 2015-07-08 18:55:16.000000000 +0200 @@ -50,7 +50,11 @@ namespace vigra { - +class DepthSplitterBase +{ +public: + virtual int GetMaximumTreeDepth() const = 0; +}; enum NodeTags { diff -urNb vigra-Version-1-10-0/include/vigra/random_forest/rf_split.hxx Vigra/include/vigra/random_forest/rf_split.hxx --- vigra-Version-1-10-0/include/vigra/random_forest/rf_split.hxx 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/include/vigra/random_forest/rf_split.hxx 2015-07-08 18:55:16.000000000 +0200 @@ -108,6 +108,11 @@ \ref SplitBase::findBestSplit() or \ref SplitBase::makeTerminalNode(). **/ + virtual int GetMaximumTreeDepth() const + { + return ext_param_.max_tree_depth; + } + template void set_external_parameters(ProblemSpec const & in) { diff -urNb vigra-Version-1-10-0/include/vigra/random_forest.hxx Vigra/include/vigra/random_forest.hxx --- vigra-Version-1-10-0/include/vigra/random_forest.hxx 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/include/vigra/random_forest.hxx 2015-07-15 14:08:18.548277915 +0200 @@ -165,6 +165,7 @@ ProblemSpec_t ext_param_; /*mutable ArrayVector tree_indices_;*/ rf::visitors::OnlineLearnVisitor online_visitor_; + bool multithreadPrediction; // enable/disable multithreaded predictProbabilities and predictLabels void reset() @@ -584,6 +585,18 @@ { vigra_precondition(features.shape(0) == labels.shape(0), "RandomForest::predictLabels(): Label array has wrong size."); + if (multithreadPrediction) + { +#pragma omp parallel for + for(int k=0; k::cast(predictLabel(rowVector(features, k), rf_default())); + } + } + else + { for(int k=0; k::cast(predictLabel(rowVector(features, k), rf_default())); } } + } /** \brief predict multiple labels with given features * @@ -1261,6 +1275,60 @@ } */ //Classify for each row. + if (multithreadPrediction) + { +#pragma omp parallel for + for(int row=0; row < rowCount(features); ++row) + { + MultiArrayView<2, U, StridedArrayTag> currentRow(rowVector(features, row)); + + // when the features contain an NaN, the instance doesn't belong to any class + // => indicate this by returning a zero probability array. + if(detail::contains_nan(currentRow)) + { + rowVector(prob, row).init(0.0); + continue; + } + + ArrayVector::const_iterator weights; + + //totalWeight == totalVoteCount! + double totalWeight = 0.0; + + //Let each tree classify... + for(int k=0; k::cast(totalWeight); + } + } + } + else + { for(int row=0; row < rowCount(features); ++row) { MultiArrayView<2, U, StridedArrayTag> currentRow(rowVector(features, row)); @@ -1309,6 +1377,7 @@ prob(row, l) /= detail::RequiresExplicitCast::cast(totalWeight); } } + } } diff -u -r Vigra.orig/include/vigra/imagecontainer.hxx Vigra/include/vigra/imagecontainer.hxx --- Vigra.orig/include/vigra/imagecontainer.hxx 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/include/vigra/imagecontainer.hxx 2017-08-26 11:02:40.079669325 +0200 @@ -760,7 +760,7 @@ /** swap contents of this array with the contents of other (STL-Container interface) */ - void swap(const ImagePyramid &other) + void swap(ImagePyramid &other) { images_.swap(other.images_); std::swap(lowestLevel_, other.lowestLevel_); diff -urNb vigra-Version-1-10-0/include/vigra/functortraits.hxx Vigra/include/vigra/functortraits.hxx --- vigra-Version-1-10-0/include/vigra/functortraits.hxx 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/include/vigra/functortraits.hxx 2022-03-17 15:15:01.637026200 +0100 @@ -195,8 +195,6 @@ VIGRA_DEFINE_STL_FUNCTOR(std::negate, VigraTrueType, VigraFalseType) VIGRA_DEFINE_STL_FUNCTOR(std::logical_not, VigraTrueType, VigraFalseType) VIGRA_DEFINE_STL_FUNCTOR(std::unary_negate, VigraTrueType, VigraFalseType) -VIGRA_DEFINE_STL_FUNCTOR(std::binder1st, VigraTrueType, VigraFalseType) -VIGRA_DEFINE_STL_FUNCTOR(std::binder2nd, VigraTrueType, VigraFalseType) #undef VIGRA_DEFINE_STL_FUNCTOR template diff -urNb vigra-Version-1-10-0/src/impex/imageinfo.cxx Vigra/src/impex/imageinfo.cxx --- vigra-Version-1-10-0/src/impex/imageinfo.cxx 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/src/impex/imageinfo.cxx 2022-03-17 15:22:20.975223000 +0100 @@ -1016,7 +1016,7 @@ do { numEndIt = std::find_if(numBeginIt, filename.rend(),(int (*)(int)) &isdigit); - numBeginIt = std::find_if(numEndIt, filename.rend(), not1(std::ptr_fun((int (*)(int))&isdigit))); + numBeginIt = std::find_if(numEndIt, filename.rend(), std::not_fn((int (*)(int))&isdigit)); if(numEndIt != filename.rend()) { diff -urNb vigra-1.10.0-src/include/vigra/separableconvolution.hxx Vigra/include/vigra/separableconvolution.hxx --- vigra-1.10.0-src/include/vigra/separableconvolution.hxx 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/include/vigra/separableconvolution.hxx 2022-03-17 23:08:05.690694437 +0100 @@ -1409,9 +1409,6 @@ {} ~InitProxy() -#ifndef _MSC_VER - throw(PreconditionViolation) -#endif { vigra_precondition(count_ == 1 || count_ == sum_, "Kernel1D::initExplicitly(): " diff -urNb vigra-1.10.0-src/src/impex/gif.cxx Vigra/src/impex/gif.cxx --- vigra-1.10.0-src/src/impex/gif.cxx 2013-11-18 17:48:16.000000000 +0100 +++ Vigra/src/impex/gif.cxx 2022-03-17 23:17:05.896364451 +0100 @@ -482,12 +482,12 @@ in_code, old_code; - register int + int bits, code, count; - register unsigned long + unsigned long datum; void_vector prefix(MaxStackSize); @@ -496,8 +496,8 @@ void_vector packet(256); void_vector indices(header.width*header.height); - register UInt8 *c; - register UInt16 *p = indices.begin(); + UInt8 *c; + UInt16 *p = indices.begin(); UInt8 data_size, @@ -624,7 +624,7 @@ int pass, x, y; - register UInt16 *q; + UInt16 *q; static int interlace_rate[4] = { 8, 8, 4, 2 }, @@ -891,9 +891,9 @@ long datum; - register int k; + int k; - register UInt8 *p; + UInt8 *p; void_vector hash_code(MaxHashTable); void_vector hash_prefix(MaxHashTable); +diff -urNb vigra-1.10.0-src/include/vigra/random_forest/rf_algorithm.hxx Vigra/include/vigra/random_forest/rf_algorithm.hxx +--- vigra-1.10.0-src/include/vigra/random_forest/rf_algorithm.hxx 2013-11-18 17:48:16.000000000 +0100 ++++ Vigra/include/vigra/random_forest/rf_algorithm.hxx 2022-03-18 08:52:17.519102162 +0100 +@@ -34,6 +34,7 @@ + /************************************************************************/ + #define VIGRA_RF_ALGORITHM_HXX + ++#include + #include + #include "splices.hxx" + #include +@@ -1151,7 +1152,7 @@ + ArrayVector indices(pr.features().shape(0)); + for(int ii = 0; ii < pr.features().shape(0); ++ii) + indices.push_back(ii); +- std::random_shuffle(indices.begin(), indices.end()); ++ std::shuffle(indices.begin(), indices.end(), std::mt19937(std::random_device()())); + for(int ii = 0; ii < rf.ext_param_.row_count_; ++ii) + { + if(!sm.is_used()[indices[ii]] && cts[pr.response()(indices[ii], 0)] < 3000) +diff -urNb vigra-1.10.0-src/include/vigra/random_forest/rf_visitors.hxx Vigra/include/vigra/random_forest/rf_visitors.hxx +--- vigra-1.10.0-src/include/vigra/random_forest/rf_visitors.hxx 2013-11-18 17:48:16.000000000 +0100 ++++ Vigra/include/vigra/random_forest/rf_visitors.hxx 2022-03-18 08:54:14.449776895 +0100 +@@ -41,6 +41,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -909,7 +910,7 @@ + { + ArrayVector oob_indices; + ArrayVector cts(class_count, 0); +- std::random_shuffle(indices.begin(), indices.end()); ++ std::shuffle(indices.begin(), indices.end(), std::mt19937(std::random_device()())); + for(int ii = 0; ii < rf.ext_param_.row_count_; ++ii) + { + if(!sm.is_used()[indices[ii]] && cts[pr.response()(indices[ii], 0)] < 40000)