31 #ifndef DISTANCETRANSFORMOP_H_
32 #define DISTANCETRANSFORMOP_H_
38 #include "drain/image/CoordinateHandler.h"
39 #include "drain/image/DistanceModelLinear.h"
40 #include "drain/image/DistanceModelExponential.h"
68 void setRadius(dist_t width, dist_t height=DistanceModel::nan_f, dist_t width2=DistanceModel::nan_f, dist_t height2=DistanceModel::nan_f){
69 distanceModel.setRadius(width, height, width2, height2);
87 mout.
note(
"discarding alpha channels, redirecting to traverseChannel(src, dst)");
97 dst.setGeometry(src.getGeometry());
145 return distanceModel;
150 return distanceModel;
156 mutable T distanceModel;
160 DistanceTransformOp(
const std::string &name,
const std::string &description,
float width,
float height,
162 DistanceModel::topol_t topology=DistanceModel::KNIGHT) :
166 parameters.
append(distanceModel.getParameters());
167 distanceModel.setTopology(topology);
170 distanceModel.setRadiusVerbatim(width, height, width, height);
174 DistanceTransformOp(
const DistanceTransformOp & op) :
ImageOp(op) {
175 parameters.
append(this->distanceModel.getParameters());
177 this->distanceModel.setParameters(op.distanceModel.getParameters());
178 this->distanceModel.update();
182 Range<int> getHorzRange(
const CoordinateHandler2D & coordinateHandler)
const ;
185 Range<int> getVertRange(
const CoordinateHandler2D & coordinateHandler)
const;
199 const double codeMax = dst.getScaling().
inv(physMax);
201 mout.
debug(
"dst of type=", Type::getTypeChar(dst.
getType()),
", scaling: ", dst.getScaling());
204 mout.info(
"ok, physical scaling [", dst.getConf().
getPhysicalRange(),
"] : ");
206 else if (Type::call<typeIsSmallInt>(dst.
getType())){
207 mout.
note(
"no physical scaling, but small int, guessing: ");
210 mout.
warn(
"no physical scaling, no small int: default ");
212 mout.
note(
"physMax=", physMax,
" => ", codeMax);
214 distanceModel.setMax(codeMax);
216 distanceModel.update();
221 void traverseDownRight(
const Channel & src,
Channel & dst)
const ;
232 Range<int> xRange = coordinateHandler.getXRange();
235 if (coordinateHandler.policy.xUnderFlowPolicy == EdgePolicy::WRAP)
236 xRange.min -= radiusHorz.backward;
238 if (coordinateHandler.policy.xOverFlowPolicy == EdgePolicy::WRAP)
239 xRange.max += radiusHorz.forward;
247 Logger mout(getImgLog(), __FILE__, __FUNCTION__);
249 Range<int> yRange = coordinateHandler.getYRange();
258 if (coordinateHandler.policy.yUnderFlowPolicy == EdgePolicy::WRAP)
259 yRange.min -= radiusVert.backward;
261 if (coordinateHandler.policy.yOverFlowPolicy == EdgePolicy::WRAP)
262 yRange.max += radiusVert.forward;
274 Logger mout(getImgLog(), __FILE__, __FUNCTION__);
277 mout.
debug(
"model max: ", getDistanceModel().getMax());
280 traverseDownRight(src,dst);
282 traverseUpLeft(dst,dst);
292 Logger mout(getImgLog(), __FILE__, __FUNCTION__);
296 mout.debug2(
"distModel:", this->distanceModel);
298 DistanceNeighbourhood chain;
299 this->distanceModel.createChain(chain,
true);
304 mout.debug2(
"coordHandler:", coordinateHandler);
327 Range<int> xRange = getHorzRange(coordinateHandler);
328 Range<int> yRange = getVertRange(coordinateHandler);
329 mout.debug2(xRange,
" - ", yRange);
345 for (p.y=yRange.min; p.y<=yRange.max; ++p.y){
346 for (p.x=xRange.min; p.x<=xRange.max; ++p.x){
348 pSafe.setLocation(p);
353 d = src2dst.fwd(src.
get<dist_t>(pSafe));
356 dTest = dst.
get<dist_t>(pSafe);
362 pTest.setLocation(pSafe.x + elem.diff.x, pSafe.y + elem.diff.y);
363 coordinateHandler.
handle(pTest);
364 dTest = this->distanceModel.decrease(dst.
get<dist_t>(pTest), elem.coeff);
384 Logger mout(getImgLog(), __FILE__, __FUNCTION__);
388 mout.
debug2(
"distModel:", this->distanceModel);
390 DistanceNeighbourhood chain;
391 this->distanceModel.createChain(chain,
false);
394 mout.
debug2(
"coordHandler:", coordinateHandler);
413 Range<int> xRange = getHorzRange(coordinateHandler);
414 Range<int> yRange = getVertRange(coordinateHandler);
415 mout.
special(xRange,
',', yRange);
417 for (p.y=yRange.max; p.y>=yRange.min; --p.y){
418 for (p.x=xRange.max; p.x>=xRange.min; --p.x){
420 pSafe.setLocation(p);
425 d = src2dst.
fwd(src.
get<dist_t>(pSafe));
428 dTest = dst.
get<dist_t>(pSafe);
434 pTest.setLocation(pSafe.x + elem.diff.x, pSafe.y + elem.diff.y);
435 coordinateHandler.
handle(pTest);
436 dTest = this->distanceModel.decrease(dst.
get<dist_t>(pTest), elem.coeff);
486 DistanceTransformLinearOp(
float horz = 10.0,
float vert = DistanceModel::nan_f, DistanceModel::topol_t topology = DistanceModel::KNIGHT):
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition: Log.h:308
Logger & special(const TT &... args)
Other useful information.
Definition: Log.h:527
Logger & note(const TT &... args)
For top-level information.
Definition: Log.h:485
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition: Log.h:426
Logger & debug(const TT &... args)
Public, yet typically used "internally", when TIMING=true.
Definition: Log.h:676
Logger & debug2(const TT &... args)
Debug information.
Definition: Log.h:686
void append(ReferenceMap &rMap, bool replace=true)
Adopts the references of r. If replace==false, only new entries are appended.
Definition: ReferenceMap.h:320
Linear scaling and physical range for image intensities.
Definition: ValueScaling.h:64
bool isPhysical() const
Returns true, physical intensity range has been set.
Definition: ValueScaling.h:281
double fwd(double x) const
Forward scaling: given encoded value x, returns corresponding value (possibly physically meaningful).
Definition: ValueScaling.h:295
const Range< double > & getPhysicalRange() const
Returns a typical or supported range for physical values.
Definition: ValueScaling.h:221
double inv(double y) const
Inverse scaling: given physically meaningful value y, returns the corresponding code value.
Definition: ValueScaling.h:301
Image with static geometry.
Definition: ImageChannel.h:60
Definition: CoordinateHandler.h:62
static const coord_overflow_t IRREVERSIBLE
Equal move in inverse direction would not result original position.
Definition: CoordinateHandler.h:74
virtual coord_overflow_t handle(int &x, int &y) const
Ensures the validity of the coordinates. If inside limits, arguments (x,y) remain intact and 0 is ret...
Definition: CoordinateHandler.h:190
Definition: DistanceModel.h:76
Definition: DistanceModelExponential.h:55
Base class for linear and exponential distances in rectangular pixel images.
Definition: DistanceModel.h:123
double requestPhysicalMax(double defaultMax=static_cast< double >(std::numeric_limits< short int >::max())) const
Returns the actual or guessed maximum physical value,.
Definition: ImageConf.h:293
T getTypeMax() const
Returns the maximum value supported by the current storage type.
Definition: ImageConf.h:281
void setPhysicalRange(const Range< double > &range, bool rescale=false)
Sets channel specific scaling instead of shared (image-level) scaling.
Definition: ImageConf.h:229
Struct for image (excluding data)
Definition: ImageConf.h:333
CoordinatePolicy coordinatePolicy
Rules to handle under- and overflows of horizontal and vertical coordinates.
Definition: ImageConf.h:383
Image with static geometry.
Definition: ImageFrame.h:67
void put(size_t i, T x)
Sets the intensity in location i to x. See \address.
Definition: ImageFrame.h:192
T get(size_t i) const
Gets the intensity at location i. See address().
Definition: ImageFrame.h:254
const std::type_info & getType() const
Get the storage type.
Definition: ImageLike.h:100
const CoordinatePolicy & getCoordinatePolicy() const
Coord policy.
Definition: ImageLike.h:167
virtual int srcAlpha() const
Tell if alpha channel(s) is required in input.
Definition: ImageMod.h:66
Base class for image processing functions.
Definition: ImageOp.h:49
ImageOp(const std::string &name=__FUNCTION__, const std::string &description="")
Definition: ImageOp.h:156
void traverseChannelsSeparately(const ImageTray< const Channel > &src, ImageTray< Channel > &dst) const
Process each (src,dst) channel pair independently. Raise error if their counts differ.
Definition: ImageOp.cpp:340
Container applicable for Channels and Images, with alpha support.
Definition: ImageTray.h:267
Definition: DataSelector.cpp:1277