Permalink
Browse files

vigranumpy: added method="turbo" to watershed functions

  • Loading branch information...
1 parent 722ad27 commit 02bd4eaad03b140ffef215782b9b1efdcdcceba8 @ukoethe committed Jun 29, 2012
Showing with 362 additions and 19 deletions.
  1. +9 −5 include/vigra/watersheds.hxx
  2. +77 −14 vigranumpy/src/core/segmentation.cxx
  3. +276 −0 vigranumpy/src/core/tws.hxx
@@ -501,12 +501,16 @@ generateWatershedSeeds(SrcIterator upperlefts, SrcIterator lowerrights, SrcAcces
}
else
{
+ LocalMinmaxOptions lm_options;
+ lm_options.neighborhood(Neighborhood::DirectionCount)
+ .markWith(1.0)
+ .allowAtBorder()
+ .allowPlateaus(options.mini == SeedOptions::ExtendedMinima);
+ if(options.thresholdIsValid<SrcType>())
+ lm_options.threshold(options.thresh);
+
localMinima(srcIterRange(upperlefts, lowerrights, sa), destImage(seeds),
- LocalMinmaxOptions().neighborhood(Neighborhood::DirectionCount)
- .markWith(1.0)
- .threshold(options.thresh)
- .allowAtBorder()
- .allowPlateaus(options.mini == SeedOptions::ExtendedMinima));
+ lm_options);
}
return labelImageWithBackground(srcImageRange(seeds), destIter(upperleftd, da),
@@ -50,6 +50,8 @@
#include <cmath>
#include <ctype.h> // tolower()
+#include "tws.hxx"
+
namespace python = boost::python;
namespace vigra
@@ -322,6 +324,8 @@ pythonExtendedLocalMinima2D(NumpyArray<2, Singleband<PixelType> > image,
return res;
}
+VIGRA_PYTHON_MULTITYPE_FUNCTOR(pyExtendedLocalMinima2D, pythonExtendedLocalMinima2D)
+
template<class PixelType>
NumpyAnyArray
pythonExtendedLocalMinima3D(NumpyArray<3, Singleband<PixelType> > volume,
@@ -592,7 +596,7 @@ python::tuple
pythonWatersheds2D(NumpyArray<2, Singleband<PixelType> > image,
int neighborhood = 4,
NumpyArray<2, Singleband<npy_uint32> > seeds = NumpyArray<2, Singleband<npy_uint32> >(),
- std::string method = "RegionGrowing",
+ std::string method = "",
SRGType srgType = CompleteGrow,
PixelType max_cost = 0.0,
NumpyArray<2, Singleband<npy_uint32> > res = NumpyArray<2, Singleband<npy_uint32> >())
@@ -603,8 +607,13 @@ pythonWatersheds2D(NumpyArray<2, Singleband<PixelType> > image,
for(unsigned int k=0; k<method.size(); ++k)
method[k] = (std::string::value_type)tolower(method[k]);
if(method == "")
- method = "regiongrowing";
-
+ {
+ if(IsSameType<PixelType, npy_uint8>::value)
+ method = "turbo";
+ else
+ method = "regiongrowing";
+ }
+
std::string description("watershed labeling, neighborhood=");
description += asString(neighborhood);
@@ -629,7 +638,20 @@ pythonWatersheds2D(NumpyArray<2, Singleband<PixelType> > image,
}
else
{
- options.seedOptions(SeedOptions().minima());
+ if(method == "turbo")
+ options.seedOptions(SeedOptions().extendedMinima());
+ else
+ options.seedOptions(SeedOptions().minima());
+ }
+
+ std::cerr << method << " watershed\n";
+
+ if(method == "turbo")
+ {
+ vigra_precondition((IsSameType<PixelType, npy_uint8>::value),
+ "watersheds(): Turbo method only works for uint8 images.");
+ options.turboAlgorithm();
+ method = "regiongrowing";
}
npy_uint32 maxRegionLabel = 0;
@@ -694,9 +716,26 @@ pythonWatersheds3D(NumpyArray<3, Singleband<PixelType> > image,
unsigned int maxRegionLabel;
if(method == "")
- method = "regiongrowing";
+ {
+ if(IsSameType<PixelType, npy_uint8>::value)
+ method = "turbo";
+ else
+ method = "regiongrowing";
+ }
- if(method == "regiongrowing")
+ if(method == "turbo")
+ {
+ vigra_precondition((IsSameType<PixelType, npy_uint8>::value),
+ "watersheds3D(): Turbo algorithm requires input dtype = uint8.");
+ vigra_precondition(neighborhood == 6,
+ "watersheds3D(): Turbo algorithm requires neighborhood = 6.");
+ vigra_precondition(srgType == CompleteGrow,
+ "watersheds3D(): Turbo algorithm requires termination = CompleteGrow.");
+ vigra_precondition(max_cost == 0,
+ "watersheds3D(): Turbo algorithm doesn't support 'max_cost'.");
+ }
+
+ if(method == "regiongrowing" || method == "turbo")
{
std::string description("watershed seeds");
@@ -771,9 +810,19 @@ pythonWatersheds3D(NumpyArray<3, Singleband<PixelType> > image,
ArrayOfRegionStatistics< SeedRgDirectValueFunctor< PixelType > > stats(maxRegionLabel);
if(neighborhood == 6)
{
- seededRegionGrowing3D(srcMultiArrayRange(image), srcMultiArray(seeds),
- destMultiArray(res),
- stats, srgType, NeighborCode3DSix(), max_cost);
+ if(method == "turbo")
+ {
+ std::cerr << "turbo watershed3d\n";
+ res = seeds;
+
+ TWS<PixelType>::exec(image, res);
+ }
+ else
+ {
+ seededRegionGrowing3D(srcMultiArrayRange(image), srcMultiArray(seeds),
+ destMultiArray(res),
+ stats, srgType, NeighborCode3DSix(), max_cost);
+ }
}
else
{
@@ -883,8 +932,20 @@ void defineSegmentation()
"6 or 26 (default).\n\n"
"For details see localMinima3D_ in the vigra C++ documentation.\n");
- def("extendedLocalMinima",
- registerConverters(&pythonExtendedLocalMinima2D<float>),
+ // def("extendedLocalMinima",
+ // registerConverters(&pythonExtendedLocalMinima2D<float>),
+ // (arg("image"),
+ // arg("marker")=1.0,
+ // arg("neighborhood") = 8,
+ // arg("out")=python::object()),
+ // "Find local minima and minimal plateaus in an image and mark them with "
+ // "the given 'marker'. Parameter 'neighborhood' specifies the pixel "
+ // "neighborhood to be used and can be 4 or 8 (default).\n\n"
+ // "For details see extendedLocalMinima_ in the vigra C++ documentation.\n"
+ // );
+
+ multidef("extendedLocalMinima",
+ pyExtendedLocalMinima2D<npy_uint8, float>(),
(arg("image"),
arg("marker")=1.0,
arg("neighborhood") = 8,
@@ -953,7 +1014,7 @@ void defineSegmentation()
(arg("image"),
arg("neighborhood") = 4,
arg("seeds")=python::object(),
- arg("method")="RegionGrowing",
+ arg("method")="",
arg("terminate")=CompleteGrow,
arg("max_cost")=0,
arg("out")=python::object()),
@@ -978,8 +1039,10 @@ void defineSegmentation()
" (with dtype=numpy.uint32).\n"
" method:\n"
" the algorithm to be used for watershed computation. Possible values:\n\n"
+ " 'Turbo':\n"
+ " (default if input dtype == uint8) use fastSeededRegionGrowing_ or tws() respectively\n"
" 'RegionGrowing':\n"
- " (default) use seededRegionGrowing_ or seededRegionGrowing3D_ respectively\n"
+ " (default if input dtype != uint8) use seededRegionGrowing_ or seededRegionGrowing3D_ respectively\n"
" 'UnionFind:\n"
" use watershedsUnionFind_ or watersheds3D_ respectively\n\n"
" terminate:\n"
@@ -1008,7 +1071,7 @@ void defineSegmentation()
(arg("volume"),
arg("neighborhood") = 6,
arg("seeds")=python::object(),
- arg("method")="RegionGrowing",
+ arg("method")="",
arg("terminate")=CompleteGrow,
arg("max_cost")=0,
arg("out")=python::object()),
Oops, something went wrong.

0 comments on commit 02bd4ea

Please sign in to comment.