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