GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/unrrdu/dist.c Lines: 17 40 42.5 %
Date: 2017-05-26 Branches: 1 20 5.0 %

Line Branch Exec Source
1
/*
2
  Teem: Tools to process and visualize scientific data and images             .
3
  Copyright (C) 2013, 2012, 2011, 2010, 2009  University of Chicago
4
  Copyright (C) 2008, 2007, 2006, 2005  Gordon Kindlmann
5
  Copyright (C) 2004, 2003, 2002, 2001, 2000, 1999, 1998  University of Utah
6
7
  This library is free software; you can redistribute it and/or
8
  modify it under the terms of the GNU Lesser General Public License
9
  (LGPL) as published by the Free Software Foundation; either
10
  version 2.1 of the License, or (at your option) any later version.
11
  The terms of redistributing and/or modifying this software also
12
  include exceptions to the LGPL that facilitate static linking.
13
14
  This library is distributed in the hope that it will be useful,
15
  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
  Lesser General Public License for more details.
18
19
  You should have received a copy of the GNU Lesser General Public License
20
  along with this library; if not, write to Free Software Foundation, Inc.,
21
  51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
*/
23
24
#include "unrrdu.h"
25
#include "privateUnrrdu.h"
26
27
#define INFO "Euclidean distance transform"
28
static const char *_unrrdu_distInfoL =
29
(INFO
30
 ". Based on \"Distance Transforms of Sampled Functions\" by "
31
 "Pedro F. Felzenszwalb and Daniel P. Huttenlocher, "
32
 "Cornell Computing and Information Science TR2004-1963. "
33
 "This function first thresholds at the specified value and then "
34
 "does the distance transform of the resulting binary image. "
35
 "The signed distance (negative values inside object) is also available. "
36
 "Distances between non-isotropic samples are handled correctly.\n "
37
 "* Uses nrrdDistanceL2 or nrrdDistanceL2Signed");
38
39
int
40
unrrdu_distMain(int argc, const char **argv, const char *me,
41
                hestParm *hparm) {
42
2
  hestOpt *opt = NULL;
43
1
  char *out, *err;
44
1
  Nrrd *nin, *nout;
45
  int pret;
46
47
1
  int E, typeOut, invert, sign;
48
1
  double thresh, bias;
49
  airArray *mop;
50
51
1
  hestOptAdd(&opt, "th,thresh", "val", airTypeDouble, 1, 1, &thresh, NULL,
52
             "threshold value to separate inside from outside");
53
1
  hestOptAdd(&opt, "b,bias", "val", airTypeDouble, 1, 1, &bias, "0.0",
54
             "if non-zero, bias the distance transform by this amount "
55
             "times the difference in value from the threshold");
56
1
  hestOptAdd(&opt, "t,type", "type", airTypeEnum, 1, 1, &typeOut, "float",
57
1
             "type to save output in", NULL, nrrdType);
58
1
  hestOptAdd(&opt, "sgn", NULL, airTypeInt, 0, 0, &sign, NULL,
59
             "also compute signed (negative) distances inside objects, "
60
             "instead of leaving them as zero");
61
1
  hestOptAdd(&opt, "inv", NULL, airTypeInt, 0, 0, &invert, NULL,
62
             "values *below* threshold are considered interior to object. "
63
             "By default (not using this option), values above threshold "
64
             "are considered interior. ");
65
1
  OPT_ADD_NIN(nin, "input nrrd");
66
1
  OPT_ADD_NOUT(out, "output nrrd");
67
68
1
  mop = airMopNew();
69
1
  airMopAdd(mop, opt, (airMopper)hestOptFree, airMopAlways);
70
71
2
  USAGE(_unrrdu_distInfoL);
72
  PARSE();
73
  airMopAdd(mop, opt, (airMopper)hestParseFree, airMopAlways);
74
75
  nout = nrrdNew();
76
  airMopAdd(mop, nout, (airMopper)nrrdNuke, airMopAlways);
77
78
  if (bias && sign) {
79
    fprintf(stderr, "%s: sorry, signed and biased transform not "
80
            "yet implemented\n", me);
81
    airMopError(mop);
82
    return 1;
83
  }
84
85
  if (sign) {
86
    E = nrrdDistanceL2Signed(nout, nin, typeOut, NULL, thresh, !invert);
87
  } else {
88
    if (bias) {
89
      E = nrrdDistanceL2Biased(nout, nin, typeOut, NULL, thresh, bias, !invert);
90
    } else {
91
      E = nrrdDistanceL2(nout, nin, typeOut, NULL, thresh, !invert);
92
    }
93
  }
94
  if (E) {
95
    airMopAdd(mop, err = biffGetDone(NRRD), airFree, airMopAlways);
96
    fprintf(stderr, "%s: error doing distance transform:\n%s", me, err);
97
    airMopError(mop);
98
    return 1;
99
  }
100
101
  SAVE(out, nout, NULL);
102
103
  airMopOkay(mop);
104
  return 0;
105
1
}
106
107
UNRRDU_CMD(dist, INFO);