00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <cstdlib>
00029 #include <functional>
00030
00031 #include <ntg/int.hh>
00032 #include <oln/basics2d.hh>
00033 #include <oln/utils/timer.hh>
00034
00035 #include <oln/lrde/ufmt/generic_salembier.hh>
00036 #include <oln/lrde/efigi/io.hh>
00037
00038
00039 void usage(char* argv[])
00040 {
00041 std::cerr << "generic max-tree computation with salembier's flooding"
00042 << " (float version, with a different comparison function)."
00043 << std::endl
00044 << "usage: " << argv[0] << " input.pfm c" << std::endl;
00045 exit(1);
00046 }
00047
00048
00049
00050 class almost_greater : public std::binary_function<float, float, bool>
00051 {
00052 public:
00053 almost_greater(float max_relative_error = 0.0000001f,
00054 float max_absolute_error = 3 * FLT_MIN) :
00055 max_relative_error_ (max_relative_error),
00056 max_absolute_error_ (max_absolute_error)
00057 {
00058 }
00059
00060 bool
00061 operator() (float a, float b)
00062 {
00063
00064
00065
00066
00067
00068 if (almost_equal_relative_or_absolute(a, b))
00069 return false;
00070 return a > b;
00071 }
00072
00073 private:
00074 bool almost_equal_relative_or_absolute(float A, float B)
00075 {
00076 if (fabs(A - B) < max_absolute_error_)
00077 return true;
00078 float relative_error;
00079 if (fabs(B) > fabs(A))
00080 relative_error = fabs((A - B) / B);
00081 else
00082 relative_error = fabs((A - B) / A);
00083 if (relative_error <= max_relative_error_)
00084 return true;
00085 return false;
00086 }
00087
00088 private:
00089 float max_relative_error_;
00090 float max_absolute_error_;
00091 };
00092
00093
00094 int main(int argc, char* argv[])
00095 {
00096 if (argc != 3)
00097 usage(argv);
00098
00099 using namespace oln;
00100 typedef image2d<float> image_t;
00101
00102 image_t input = efigi::load_pfm(argv[1]);
00103 assert (input.has_impl());
00104
00105 int c = atoi(argv[2]);
00106 if (not (c == 2 or c == 4 or c == 8))
00107 usage(argv);
00108
00109 neighborhood2d nbh;
00110 if (c == 2)
00111 nbh.add(dpoint2d(0, 1));
00112 else
00113 nbh = c == 4 ? neighb_c4() : neighb_c8();
00114
00115 typedef lrde::ufmt::generic_salembier<image_t, almost_greater> algorithm_t;
00116
00117 algorithm_t run(input, nbh);
00118 utils::timer t;
00119 t.start();
00120 run.go();
00121 t.stop();
00122 std::cout << "n level roots = " << run.n_level_roots() << std::endl
00123 << "elapsed time = " << t.last_time() << std::endl;
00124 }