Skip to content

Commit

Permalink
Adjust seg (#75)
Browse files Browse the repository at this point in the history
* add unit test for preprocess; remove object contact is really working

* inplace segmentation of watershed

* seeded watershed

* add robin map github repo as submodule since robin_map is not updated in conda-forge

* make the priority queue more general to use

* update the edit of priority queue

* move priority queue to utils

* move priority queue back to segmentation since the functions are built in for the edge type

* seeded watershed compiles, but runs with core dump error

* compilation in macbook pro

* unit test for seeded watershed. the correctness of the result is not checked

* add segmentation module with 2d seeded watershed

* fixed the bug; the code still has a lot of assertion

* remove a lot of assertions

* test seeded watershed 3d
  • Loading branch information
xiuliren authored Mar 28, 2022
1 parent e0db485 commit 3c895c0
Show file tree
Hide file tree
Showing 18 changed files with 375 additions and 100 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.nfs*
*.code-workspace
*.DS_Store

Expand Down
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "cpp/third-party/robin-map"]
path = cpp/third-party/robin-map
url = https://github.com/Tessil/robin-map.git
path = cpp/third-party/robin-map
url = https://github.com/Tessil/robin-map.git
36 changes: 28 additions & 8 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,39 @@
{
"configurations": [
{
"name": "Mac",
"name": "centos",
"includePath": [
"~/code/reneu/cpp/include",
"~/opt/anaconda3/envs/reneu/include",
"~/opt/anaconda3/envs/reneu/include/python3.8",
"~/opt/anaconda3/envs/reneu/lib/python3.8/site-packages/numpy/core/include"
"${HOME}/code/reneu/cpp/include",
"${CONDA_PREFIX}/include/python3.8",
"${CONDA_PREFIX}/include",
"${CONDA_PREFIX}/lib/python3.8/site-packages/numpy/core/include",
"${workspaceFolder}/cpp/third-party/robin-map/include"
],
"defines": [],
"macFrameworkPath": [],
"compilerPath": "/usr/bin/clang",
"compilerPath": "/cm/shared/sw/nix/store/hmphldjnv7440cwpv29ph5d5bp3lbxz5-gcc-11.2.0/bin/gcc",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "clang-x64",
"cppStandard": "c++20",
"intelliSenseMode": "linux-gcc-x64",
"configurationProvider": "ms-vscode.cmake-tools"
},
{
"name": "MacOS",
"includePath": [
"${workspaceFolder}/cpp/include",
"${CONDA_PREFIX}/include/python3.8",
"${CONDA_PREFIX}/include",
"${HOME}/opt/anaconda3/envs/reneu/include",
"${CONDA_PREFIX}/lib/python3.8/site-packages/numpy/core/include",
"${workspaceFolder}/cpp/third-party/robin-map/include"
],
"defines": [],
"macFrameworkPath": [
"/System/Library/Frameworks"
],
"cStandard": "c17",
"cppStandard": "c++20",
"intelliSenseMode": "macos-clang-x64",
"configurationProvider": "ms-vscode.cmake-tools"
}
],
Expand Down
27 changes: 14 additions & 13 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ cmake_minimum_required(VERSION 3.12.0)
set(RENEU_VERSION 0.2.0)
project(libreneu VERSION ${RENEU_VERSION} LANGUAGES CXX)

# add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/third-party/robin-map)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third-party/robin-map/include)

set(CMAKE_THREAD_LIBS_INIT "-lpthread")
set(CMAKE_HAVE_THREADS_LIBRARY 1)
set(CMAKE_USE_WIN32_THREADS_INIT 0)
Expand All @@ -18,7 +21,6 @@ set(xtensor_DIR ${CONDA_PREFIX}/lib/cmake/xtensor)
set(xtensor-python_DIR ${CONDA_PREFIX}/lib/cmake/xtensor-python)
set(xtl_DIR ${CONDA_PREFIX}/lib/cmake/xtl)

add_subdirectory(third-party/robin-map)

set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED OFF)
Expand All @@ -35,14 +37,10 @@ if(Boost_NO_SYSTEM_PATH)
endif(Boost_NO_SYSTEM_PATH)
find_package(Boost REQUIRED serialization)

set(RENEU_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
include_directories(${NUMPY_INCLUDE_DIR} ${RENEU_INCLUDE_DIR}
${CONDA_PREFIX}/include ${BOOST_INCLUDEDIR})

set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(PYBIND11_CPP_STANDARD "-std=c++17")
set(PYBIND11_CPP_STANDARD "-std=c++20")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/../bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/../python/reneu/lib)
Expand All @@ -52,14 +50,19 @@ find_package(BLAS REQUIRED)
find_package(PythonInterp 3 REQUIRED)
find_package(PythonLibs 3 REQUIRED)
find_package(Numpy REQUIRED)
#find_package(Python3 REQUIRED COMPONENTS Numpy)
# find_package(Python3 REQUIRED COMPONENTS Numpy)
find_package(pybind11 REQUIRED)
find_package(xtensor REQUIRED)
find_package(xtensor-python REQUIRED)
find_package(xtensor-blas REQUIRED)
# find_package(tsl REQUIRED)
#find_package(tsl_robin_map REQUIRED)
# find_package(tsl-robin-map REQUIRED)
# find_package(TBB REQUIRED)

set(RENEU_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
include_directories(${NUMPY_INCLUDE_DIR} ${RENEU_INCLUDE_DIR}
${CONDA_PREFIX}/include ${BOOST_INCLUDEDIR})

pybind11_add_module(skeleton ${CMAKE_CURRENT_SOURCE_DIR}/skeleton.cpp)
pybind11_add_module(segmentation ${CMAKE_CURRENT_SOURCE_DIR}/segmentation.cpp)
pybind11_add_module(synapse ${CMAKE_CURRENT_SOURCE_DIR}/synapse.cpp)
Expand All @@ -71,10 +74,8 @@ target_link_libraries(skeleton PRIVATE ${BLAS_LIBRARIES})

message("boost libarries: ${Boost_LIBRARIES}")
target_include_directories(segmentation PUBLIC ${NUMPY_INCLUDE_DIR} ${RENEU_INCLUDE_DIR})
target_link_libraries(segmentation PRIVATE ${Boost_LIBRARIES} tsl::robin_map)

# target_link_libraries(segmentation ${Boost_LIBRARIES} )
# target_link_libraries(segmentation "${Boost_LIBRARIES}/libboost_serialization.dylib" )
#target_link_libraries(segmentation PRIVATE ${Boost_LIBRARIES} tsl::robin_map)
target_link_libraries(segmentation PRIVATE ${Boost_LIBRARIES})

# options
option(BUILD_TESTS "build test suite" OFF)
Expand Down
24 changes: 7 additions & 17 deletions cpp/include/reneu/segmentation/preprocess.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "reneu/type_aliase.hpp"
#include <xtensor/xview.hpp>
#include "reneu/utils/print.hpp"

namespace reneu{

Expand All @@ -15,18 +16,18 @@ void remove_contact_1d(SEG1D seg1d){
if(seg1d(x)>0 && seg1d(x-1)>0 && seg1d(x)!=seg1d(x-1)){
seg1d(x) = 0;
seg1d(x-1) = 0;
std::cout<<x<<", ";
// std::cout<<x<<", ";
}
}
std::cout<<std::endl;
// std::cout<<std::endl;
}

/**
* @brief remove the object boundary voxel if it contacted another object
*
* @param seg the input plain segmentation
*/
void remove_contact(Segmentation&& seg){
auto remove_contact(PySegmentation& seg){
// z direction
for(std::size_t y=0; y<seg.shape(1); y++){
for(std::size_t x=0; x<seg.shape(2); x++){
Expand All @@ -47,14 +48,7 @@ void remove_contact(Segmentation&& seg){
remove_contact_1d(xt::view(seg, z, y, xt::all()));
}
}

}

auto py_remove_contact(PySegmentation& pySeg){
remove_contact(pySeg);
// remove_contact(std::forward(pySeg));
// return std::forward(pySeg);
// return pySeg;
// reneu::utils::print_array(seg);
}

/*
Expand Down Expand Up @@ -119,9 +113,9 @@ void fill_background_with_affinity_guidance2d(
}
}

template<class SEG, class AFFS, class AFF_EDGE>
void fill_background_with_affinity_guidance(
SEG& seg, const AFFS& affs, const AFF_EDGE& threshold){
PySegmentation& seg, const PyAffinityMap& affs,
const aff_edge_t& threshold){
for(size_t z = 0; z<seg.shape(0); z++){
auto seg2d = xt::view(seg, z, xt::all(), xt::all());
auto affx2d = xt::view(affs, 0, z, xt::all(), xt::all());
Expand All @@ -130,9 +124,5 @@ void fill_background_with_affinity_guidance(
}
}

auto py_fill_background_with_affinity_guidance(PySegmentation& pySeg, const PyAffinityMap& pyAffs, const aff_edge_t& threshold){
fill_background_with_affinity_guidance(pySeg, pyAffs, threshold);
return pySeg;
}

} // namespace reneu
23 changes: 2 additions & 21 deletions cpp/include/reneu/segmentation/priority_queue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,11 @@

namespace reneu{

struct EdgeInQueue{
segid_t segid0;
segid_t segid1;
aff_edge_t aff;
size_t version;

// constructor for emplace operation
EdgeInQueue(const segid_t& segid0_, const segid_t& segid1_, const aff_edge_t& aff_, const std::size_t& version_):
segid0(segid0_), segid1(segid1_), aff(aff_), version(version_){}

bool operator<(const EdgeInQueue& other) const {
return aff < other.aff;
}
};
// struct LessThanByAff{
// bool operator()(const EdgeInQueue& lhs, const EdgeInQueue& rhs) const {
// return lhs.aff < rhs.aff;
// }
// };
// using PriorityQueue = std::priority_queue<EdgeInQueue, std::vector<EdgeInQueue>, std::less<EdgeInQueue>>;

template<class E>
class PriorityQueue{
private:
std::vector<EdgeInQueue> _edges;
std::vector<E> _edges;

public:
PriorityQueue(): _edges({}) { }
Expand Down
28 changes: 26 additions & 2 deletions cpp/include/reneu/segmentation/region_graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,30 @@ namespace reneu{

class RegionGraph;

struct EdgeInHeap{
segid_t segid0;
segid_t segid1;
aff_edge_t aff;
size_t version;

// constructor for emplace operation
EdgeInHeap(
const segid_t& segid0_, const segid_t& segid1_,
const aff_edge_t& aff_, const std::size_t& version_):
segid0(segid0_), segid1(segid1_), aff(aff_), version(version_){}

bool operator<(const EdgeInHeap& other) const {
return aff < other.aff;
}
};
// struct LessThanByAff{
// bool operator()(const EdgeInQueue& lhs, const EdgeInQueue& rhs) const {
// return lhs.aff < rhs.aff;
// }
// };
// using PriorityQueue = std::priority_queue<EdgeInQueue, std::vector<EdgeInQueue>, std::less<EdgeInQueue>>;


class RegionEdge{
public:
// we use the same type for both value for type stability in the average division.
Expand Down Expand Up @@ -170,7 +194,7 @@ inline void _accumulate_edge(const segid_t& segid0, const segid_t& segid1, const


auto _build_priority_queue (const aff_edge_t& threshold) const {
PriorityQueue heap;
PriorityQueue<EdgeInHeap> heap;
for(const auto& [segid0, neighbors0] : _segid2neighbor){
for(const auto& [segid1, edgeIndex] : neighbors0){
// the connection is bidirectional,
Expand All @@ -192,7 +216,7 @@ auto _build_priority_queue (const aff_edge_t& threshold) const {
}

auto _merge_segments(segid_t& segid0, segid_t& segid1, const RegionEdge& edge,
PriorityQueue& heap,
PriorityQueue<EdgeInHeap>& heap,
const aff_edge_t& affinityThreshold){

// always merge object with less neighbors to more neighbors
Expand Down
2 changes: 1 addition & 1 deletion cpp/include/reneu/segmentation/region_graph_chunk.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ inline auto _frozen_neighbor_flag(const segid_t& segid0, const aff_edge_t& thres


auto _build_priority_queue (const aff_edge_t& threshold) const {
PriorityQueue heap;
PriorityQueue<EdgeInHeap> heap;
for(const auto& [segid0, neighbors0] : _segid2neighbor){
for(const auto& [segid1, edgeIndex] : neighbors0){
// the connection is bidirectional,
Expand Down
Loading

0 comments on commit 3c895c0

Please sign in to comment.