1 //This is brl/bseg/bvxm/pro/processes/bvxm_detect_edge_tangent_process.cxx
2 #include "bvxm_detect_edge_tangent_process.h"
3 //:
4 // \file
5
6 #include <sdet/sdet_img_edge.h>
7
8 #include <bprb/bprb_func_process.h>
9 #include <bprb/bprb_parameters.h>
10 #include <brdb/brdb_value.h>
11 #include <bvxm/bvxm_voxel_world.h>
12 #include <bvxm/bvxm_image_metadata.h>
13 #include <sdet/sdet_detector.h>
14 #include <sdet/sdet_fit_lines.h>
15 #include <vdgl/vdgl_digital_curve.h>
16 #include <vdgl/vdgl_edgel.h>
17 #include <vdgl/vdgl_edgel_chain.h>
18 #include <vdgl/vdgl_interpolator.h>
19 #include "vil/vil_image_view.h"
20 #include "vil/vil_convert.h"
21 #include <vsol/vsol_curve_2d_sptr.h>
22 #include <vsol/vsol_line_2d.h>
23 #include <vsol/vsol_point_2d.h>
24 #include <vtol/vtol_edge_2d.h>
25 #include "vgl/vgl_line_2d.h"
26
27 //: initialize input and output types
bvxm_detect_edge_tangent_process_cons(bprb_func_process & pro)28 bool bvxm_detect_edge_tangent_process_cons(bprb_func_process& pro)
29 {
30 using namespace bvxm_detect_edge_tangent_process_globals;
31 // process takes 1 input:
32 //input[0]: input grayscale image
33 //input[1]: string indicating the output format
34 std::vector<std::string> input_types_(n_inputs_);
35 input_types_[0] = "vil_image_view_base_sptr";
36 input_types_[1] = "vcl_string";
37 if (!pro.set_input_types(input_types_))
38 return false;
39
40 // process has 1 output image with 3 bands:
41 // output[0]: output edge image with 3 planes
42 // case pos_dir
43 // plane 0 - sub-pixel column position of the edge.
44 // Negative value indicates no edge is present
45 // plane 1 - sub-pixel row position of the edge.
46 // Negative value indicates no edge is present
47 // plane 2 - Orientation of local edge tangent direction in radians
48 // range is [0, 2pi).
49 // case line_2d
50 // plane 0 - line coefficient a --
51 // |-- components of line normal vector
52 // plane 1 - line coefficient b --
53 //
54 // plane 2 - line coefficient c
55
56 std::vector<std::string> output_types_(n_outputs_);
57 output_types_[0] = "vil_image_view_base_sptr";
58 return pro.set_output_types(output_types_);
59 }
60
61 //: generates the edge map
bvxm_detect_edge_tangent_process(bprb_func_process & pro)62 bool bvxm_detect_edge_tangent_process(bprb_func_process& pro)
63 {
64 using namespace bvxm_detect_edge_tangent_process_globals;
65
66 if (!pro.verify_inputs())
67 {
68 std::cout << pro.name() << " Invalid inputs" << std::endl;
69 return false;
70 }
71
72 // get inputs
73 // image
74 vil_image_view_base_sptr input_image_sptr = pro.get_input<vil_image_view_base_sptr>(0);
75
76 //check input validity
77 if (!input_image_sptr) {
78 std::cout << pro.name() <<" :-- null input image\n";
79 return false;
80 }
81
82 vil_image_view<vxl_byte> input_image =
83 *vil_convert_cast(vxl_byte(), input_image_sptr);
84
85 std::string out_type = pro.get_input<std::string>(1);
86 // get parameters
87 double noise_multiplier=1.5, smooth=1.5;
88 bool automatic_threshold=false, junctionp=false, aggressive_junction_closure=false;
89
90 pro.parameters()->get_value(param_noise_multiplier_, noise_multiplier);
91 pro.parameters()->get_value(param_smooth_, smooth);
92 pro.parameters()->get_value(param_automatic_threshold_, automatic_threshold);
93 pro.parameters()->get_value(param_junctionp_, junctionp);
94 pro.parameters()->get_value(param_aggressive_junction_closure_, aggressive_junction_closure);
95 #if 0
96 std::cout << "Edge detection parameters\n";
97 pro.parameters()->print_all(std::cout);
98 #endif
99 vil_image_view<float> edge_image =
100 sdet_img_edge::detect_edge_tangent(input_image,
101 noise_multiplier,
102 smooth,
103 automatic_threshold,
104 junctionp,
105 aggressive_junction_closure);
106
107 // return the output edge image in pos_dir format
108 if (out_type=="pos_dir") {
109 pro.set_output_val<vil_image_view_base_sptr>(0,new vil_image_view<float>(edge_image));
110 return true;
111 }
112 //else convert to line format
113 if (out_type == "line_2d") {
114 unsigned ni = edge_image.ni(), nj = edge_image.nj();
115 auto* line_image = new vil_image_view<float>(ni, nj, 3);
116 line_image->fill(-2.0f);
117 for (unsigned j = 0; j<nj; ++j)
118 for (unsigned i = 0; i<ni; ++i) {
119 float x = edge_image(i,j,0);
120 float y = edge_image(i,j,1);
121 if (x<0||y<0)
122 continue;
123 float angle = edge_image(i,j,2);
124 vgl_vector_2d<float> tangent(std::cos(angle), std::sin(angle));
125 vgl_point_2d<float> pt(x,y);
126 vgl_line_2d<float> l(pt, tangent);
127 float a = l.a(), b = l.b(), c = l.c();
128 float norm = std::sqrt(a*a+b*b);
129 a/=norm; b/=norm; c/=norm;
130 (*line_image)(i,j,0)= a;
131 (*line_image)(i,j,1)= b;
132 (*line_image)(i,j,2)= c;
133 }
134 pro.set_output_val<vil_image_view_base_sptr>(0, line_image);
135 return true;
136 }
137 return false;
138 }
139