1 // This is gel/gevd/gevd_region_proc.cxx
2 #include "gevd_region_proc.h"
3 //:
4 // \file
5 // See gevd_region_proc.h for documentation
6 #include <gevd/gevd_float_operators.h>
7 #include <gevd/gevd_detector.h>
8 #include <gevd/gevd_clean_edgels.h>
9 #include <gevd/gevd_edgel_regions.h>
10 #include <vtol/vtol_intensity_face.h>
11
12 //---------------------------------------------------------------
13 // Constructors
14 //
15 //----------------------------------------------------------------
16
17 //: constructor from a parameter block (the only way)
18 //
gevd_region_proc()19 gevd_region_proc::gevd_region_proc()
20 {
21 debug_=false;
22 //debug_data_ = 0;
23 //roi_proc_ = 0;
24 buf_ = nullptr;
25 }
26
27 //:Default Destructor
~gevd_region_proc()28 gevd_region_proc::~gevd_region_proc()
29 {
30 delete buf_;
31 }
32
33 //---------------------------------------------------------
34 //: Extract the region of interest from image_ as a BufferXY.
35 //
get_image_buffer(vil1_image & image)36 gevd_bufferxy* gevd_region_proc::get_image_buffer(vil1_image& image)
37 {
38 if (!image)
39 return nullptr;
40 if (image.planes() != 1)
41 return nullptr;
42
43 int wd = image.width();
44 int ht = image.height();
45 int sz = image.components() * image.bits_per_component(); // bits per pixel
46 auto* buf = new gevd_bufferxy(wd, ht, sz);
47 image.get_section(buf->GetBuffer(), 0, 0, wd, ht);
48 return buf;
49 }
50
51 //---------------------------------------------------------
52 //: Convert buf to a floating point buffer
53 //
get_float_buffer(gevd_bufferxy * buf)54 gevd_bufferxy* gevd_region_proc::get_float_buffer(gevd_bufferxy* buf)
55 {
56 if (!buf)
57 return nullptr;
58 auto* fbuf = new gevd_bufferxy(buf->GetSizeX(),
59 buf->GetSizeY(),
60 8*sizeof(float));
61 gevd_float_operators::BufferToFloat(*buf, *fbuf);
62 return fbuf;
63 }
64
65
66 //---------------------------------------------------------
67 // convert a float buffer back to 16 bits/pixel
68 //
put_float_buffer(gevd_bufferxy * fbuf)69 gevd_bufferxy* gevd_region_proc::put_float_buffer(gevd_bufferxy* fbuf)
70 {
71 if (!fbuf)
72 return nullptr;
73
74 auto* pbuf = new gevd_bufferxy(fbuf->GetSizeX(), fbuf->GetSizeY(), 16);
75 gevd_float_operators::FloatToBuffer(*fbuf, *pbuf);
76 return pbuf;
77 }
78 //-------------------------------------------------------------------------
79 //: Set the image to be processed
80 //
set_image(vil1_image & image)81 void gevd_region_proc::set_image(vil1_image& image)
82 {
83 if (!image)
84 {
85 std::cout <<"In gevd_region_proc::set_image(.) - null input\n";
86 return;
87 }
88 regions_valid_ = false;
89 image_ = image;
90 if (buf_)
91 {
92 delete buf_;
93 buf_ = nullptr;
94 }
95 //Expand by expand_scale_
96 if (expand_scale_==1.0f)
97 {
98 buf_ = this->get_image_buffer(image_);
99 return;
100 }
101 else if (expand_scale_==2.0f)
102 {
103 gevd_bufferxy* temp = this->get_image_buffer(image_);
104 if (!temp)
105 {
106 std::cout <<"In gevd_region_proc::set_image(.) "
107 <<"- couldn't get gevd_bufferxy from the image\n";
108 return;
109 }
110 gevd_bufferxy* fbuf = this->get_float_buffer(temp);
111 gevd_bufferxy* expand = nullptr;
112 gevd_float_operators::ExpandBy2(*fbuf, expand, burt_adelson_factor_);
113 gevd_float_operators::TruncateToPositive(*expand);
114 buf_ = this->put_float_buffer(expand);
115 delete temp;
116 delete fbuf;
117 delete expand;
118 return;
119 }
120 else if (expand_scale_==0.5f)
121 {
122 gevd_bufferxy* temp = this->get_image_buffer(image_);
123 if (!temp)
124 {
125 std::cout <<"In gevd_region_proc::set_image(.) "
126 <<"- couldn't get gevd_bufferxy from the image\n";
127 return;
128 }
129 gevd_bufferxy* fbuf = this->get_float_buffer(temp);
130 gevd_bufferxy* shrink = nullptr;
131 gevd_float_operators::ShrinkBy2(*fbuf, shrink, burt_adelson_factor_);
132 gevd_float_operators::TruncateToPositive(*shrink);
133 buf_ = this->put_float_buffer(shrink);
134 delete temp;
135 delete fbuf;
136 delete shrink;
137 return;
138 }
139 std::cout <<"In gevd_region_proc::set_image(.) - invalid expand scale factor\n";
140 }
141
142 //--------------------------------------------------------------------------
143 //: extract a set of vdgl_poly_intensity_face(s)
extract_regions()144 void gevd_region_proc::extract_regions()
145 {
146 if (regions_valid_)
147 return;
148
149 // Check the image
150 if (!buf_)
151 {
152 std::cout << "In gevd_region_proc::extract_regions() - no image\n";
153 return;
154 }
155
156 std::cout << "gevd_region_proc::extract_regions(): sizeX = "
157 << buf_->GetSizeX() << " sizeY = " << buf_->GetSizeY() << std::endl;
158
159 //Process the image to extract regions
160 regions_.clear();
161
162 // -tpk- need to pass along the scaled image rather than the orignal
163 gevd_detector detector ( image_);
164
165 //could move this all back into detector_params
166 detector.junctionFactor = 1.0;
167 detector.contourFactor = 2.0;
168 detector.minLength = 4;
169 detector.junctionp = true;
170 detector.smooth = 2.0;
171 detector.borderp = true;
172
173 detector.DoContour();
174
175 std::vector<vtol_edge_2d_sptr> * edgels = detector.GetEdges();
176
177 if (edgels->empty()) {
178 std::cout
179 << "In gevd_region_proc::extract_regions()- No Edgels were computed\n";
180 return;
181 }
182 #if 0 // commented out
183 std::vector<vtol_edge_2d_sptr>::iterator eit; = edgels.begin();
184 for (eit = edgels->begin(); eit != edgels->end(); eit++)
185 {
186 std::cout << "Edgel output from DoContour:";
187 (*eit)->describe(std::cout,2);
188 }
189
190 gevd_detector det(dp_);
191 std::vector<vtol_edge_2d_sptr> broken_edgels;
192 det.DoBreakCorners(edgels, broken_edgels);
193 #endif
194
195 gevd_clean_edgels cl;
196 std::vector<vtol_edge_2d_sptr> clean_edgels;
197 cl.DoCleanEdgelChains(*edgels, clean_edgels);
198 if (clean_edgels.empty()) {
199 std::cout << "In gevd_region_proc::extract_regions()- All edges removed by "
200 "clean\n";
201 return;
202 }
203 gevd_edgel_regions er(debug_);
204 er.set_magnification(expand_scale_);
205 //if (verbose_)
206 // er.SetVerbose();
207
208 std::vector<vtol_intensity_face_sptr> faces;
209 //float xo = roi_proc_->get_xo(), yo = roi_proc_->get_yo();
210 er.compute_edgel_regions(buf_, clean_edgels, faces);
211 #if 0 // commented out
212 // Transform the extracted region boundaries if necessary
213 if (expand_scale_!=0.0f)
214 {
215 float si = 1.0f/expand_scale_;
216 //We use a TwoChain to provide a superior to the set of Faces
217 //so that the standard ::TaggedTransform can be used to
218 //transform IntensityFace(expand_scale_) segmented at an expanded scale.
219 TwoChain_ref tc = new TwoChain(faces.length());
220 for (std::vector<IntensityFace*>::iterator fit = faces.begin();
221 fit != faces.end(); fit++)
222 tc->add_face((Face*)(*fit), '1');
223 //Coordinates are defined at the center of a pixel
224 CoolTransform minus=CoolTransform::translation(-0.5, -0.5, 0.0);
225 CoolTransform plus=CoolTransform::translation(0.5+xo, 0.5+yo, 0.0);
226 CoolTransform scale = CoolTransform::stretching(si, si, 1.0);
227 CoolTransform t = CoolTransform::identity();
228 //Concatenate the transforms
229 t *= minus;
230 t *= scale;
231 t *= plus;
232 tc->TaggedTransform(t);
233 }
234 #endif
235 //Copy the faces to a vector
236 std::vector<vtol_intensity_face_sptr>::iterator fit;
237 for ( fit = faces.begin(); fit != faces.end(); fit++)
238 {
239 //joe mod
240 //vtol_intensity_face_ref ifr = (*fit);
241 // if (!roi_proc_->inside_roi_mask(ifr))
242 //if (!roi_proc_->inside_process_rois(ifr))
243 continue; // hence this for loop is void! - PVr
244 //vtol_intensity_face_sptr intf = (*fit);
245 //std::vector<OneChain*>* chains = intf->OneChains();
246 //vdgl_digital_region * dr = intf->cast_to_digital_region();
247 //vdgl_poly_intensity_face_ref rf = new vdgl_poly_intensity_face(chains, *dr);
248 //regions_.push_back(dr);
249 //delete chains;
250 //end joe mod
251 }
252 regions_valid_ = true;
253 }
254 //----------------------------------------------------------
255 //: Clear internal storage
256 //
clear()257 void gevd_region_proc::clear()
258 {
259 regions_.clear();
260 }
261