contrib/brl/bseg/brip/brip_quadtree_utils.txx
Go to the documentation of this file.
00001 #ifndef brip_quadtree_utils_txx_
00002 #define brip_quadtree_utils_txx_
00003 #include "brip_quadtree_utils.h"
00004 //:
00005 // \file
00006 
00007 template <class T>
00008 void brip_quadtree_utils<T>::
00009 fill_image_region(brip_quadtree_node_base_sptr node,
00010                   vil_image_view<T>& img)
00011 {
00012   if (!node)
00013     return;
00014   if (!node->data_valid())
00015     return;
00016   unsigned iul, jul, ilr, jlr;
00017   node->region(iul, jul, ilr, jlr);
00018   brip_quadtree_node<T>* fn = dynamic_cast<brip_quadtree_node<T>*>(node.ptr());
00019   float data = fn->data();
00020   for (unsigned j = jul; j<=jlr; ++j)
00021     for (unsigned i = iul; i<=ilr; ++i)
00022       img(i,j)=data;
00023 }
00024 
00025 template <class T>
00026 void brip_quadtree_utils<T>::
00027 fill_image_from_node(brip_quadtree_node_base_sptr node,
00028                      vil_image_view<T>& img)
00029 {
00030   if (!node)
00031     return;
00032   //fill according to this node's data
00033   //  fill_region(node, img);
00034   brip_quadtree_utils<T>::fill_image_region(node, img);
00035   // base case: check if no children
00036   if (!node->n_children())
00037     return;
00038 
00039   // recursion step
00040   for (unsigned i = 0; i<2; ++i)
00041     for (unsigned j = 0; j<2; ++j)
00042       fill_image_from_node(node->child(i,j), img);
00043 }
00044 
00045 template <class T>
00046 void brip_quadtree_utils<T>::
00047 extract_nodes_from_image(vil_image_view<T> const & img,
00048                          vil_image_view<bool> const & mask,
00049                          vil_image_view<T> const& parent_img,
00050                          vil_image_view<bool> const& parent_mask,
00051                          unsigned scale,
00052                          vbl_array_2d<brip_quadtree_node_base_sptr>& nodes)
00053 {
00054   // the image has two types of pixel values: valid and invalid
00055   // the invalid values are indicated by the mask plane = false
00056   // invalid pixels do not generate quadtree nodes
00057   // the size of nodes is 1/2 of the image dimensions
00058   unsigned ni = img.ni(), nj = img.nj();
00059   nodes.resize(nj/2, ni/2);
00060   nodes.fill(0);
00061   bool parent = parent_img.ni()>0;
00062   for (unsigned j = 0; j<nj; j+=2)
00063     for (unsigned i = 0; i<ni; i+=2)
00064     {
00065       bool require_node = false;
00066       for (unsigned k =0; k<=1&&!require_node; ++k)
00067         for (unsigned m =0; m<=1&&!require_node; ++m)
00068           if (mask(i+m, j+k))
00069             require_node = true;
00070       if (require_node)
00071       {
00072         // upper left corner of 1/2 size quadtree node
00073         unsigned iul = i*scale, jul = j*scale;
00074         // lower left corner of 1/2 size quadtree node
00075         unsigned ilr = iul + 2*scale -1;
00076         unsigned jlr = jul + 2*scale -1;
00077         // upper left corner of 1/2 size quadtree node
00078         brip_quadtree_node<T>* nn;
00079         if (parent && parent_mask(i/2, j/2))
00080           nn = new brip_quadtree_node<T>(iul, jul, ilr, jlr,
00081                                          parent_img(i/2, j/2));
00082         else
00083           nn = new brip_quadtree_node<T>(iul, jul, ilr, jlr);
00084         nodes[j/2][i/2]= nn;
00085         // fill out the children, there is at least one
00086         for (unsigned k =0; k<2; ++k)
00087           for (unsigned m =0; m<2; ++m){
00088             unsigned r = j+k, c = i+m;
00089             if (mask(c, r))
00090             {
00091               // upper left corner of child node
00092               unsigned iulc = c*scale, julc = r*scale;
00093               //lower right corner of child node
00094               unsigned ilrc = iulc + scale -1;
00095               unsigned jlrc = julc + scale -1;
00096               brip_quadtree_node<T>* cn =
00097                 new brip_quadtree_node<T>(iulc, julc,
00098                                           ilrc, jlrc,
00099                                           img(c,r));
00100               nn->set_child(k,m, cn);
00101               cn->set_parent(nn);
00102             }
00103           }
00104       }
00105     }
00106 }
00107 
00108 //: attach children from prev to the parents in the nodes array
00109 template <class T>
00110 void brip_quadtree_utils<T>::
00111 connect_children(vbl_array_2d<brip_quadtree_node_base_sptr>& nodes,
00112                  unsigned scale,
00113                  vbl_array_2d<brip_quadtree_node_base_sptr> const& prev)
00114 {
00115   unsigned nrow = nodes.rows(), ncol = nodes.cols();
00116   for (unsigned r = 0; r<nrow; ++r)
00117     for (unsigned c = 0; c<ncol; ++c)
00118       for (unsigned k =0; k<2; ++k)
00119         for (unsigned m =0; m<2; ++m) {
00120           unsigned rp = 2*r+k, cp = 2*c+m;
00121           if (prev[rp][cp]) {
00122             if (!nodes[r][c]) {
00123               // upper left corner of new node
00124               unsigned iul = c*scale, jul = r*scale;
00125               //lower right corner of new node
00126               unsigned ilr = iul + scale -1;
00127               unsigned jlr = jul + scale -1;
00128               nodes[r][c]=new brip_quadtree_node<T>(iul,jul, ilr, jlr);
00129             }
00130             else {
00131               nodes[r][c]->set_child(k,m,prev[rp][cp]);
00132               prev[rp][cp]->set_parent(nodes[r][c]);
00133             }
00134           }
00135         }
00136 }
00137 
00138 template <class T>
00139 void brip_quadtree_utils<T>::
00140 quadtrees_from_pyramid(vcl_vector<vil_image_view<T> > levels,
00141                        vcl_vector<vil_image_view<bool> > masks,
00142                        vbl_array_2d<brip_quadtree_node_base_sptr>& roots)
00143 {
00144   //start at the base image of the pyramid, i.e. levels[0].
00145   //at the end a vbl array with quad-tree nodes will be available.
00146   unsigned scale = 1;
00147   unsigned n_levels = levels.size();
00148   if (n_levels<2)
00149     return;
00150   vil_image_view<T> parent_img = levels[1];
00151   vil_image_view<bool> parent_mask = masks[1];
00152 
00153   vbl_array_2d<brip_quadtree_node_base_sptr> prev;
00154   brip_quadtree_utils<T>::extract_nodes_from_image(levels[0],
00155                                                    masks[0],
00156                                                    parent_img,
00157                                                    parent_mask,
00158                                                    scale,
00159                                                    prev);
00160   scale = 2;
00161   for (unsigned lev = 1; lev<n_levels; ++lev)
00162   {
00163     if (lev<n_levels-1) {
00164       parent_img = levels[lev+1];
00165       parent_mask = masks[lev+1];
00166     }
00167     else {
00168       parent_img = vil_image_view<T>();
00169       parent_mask = vil_image_view<bool>();
00170     }
00171     brip_quadtree_utils<T>::extract_nodes_from_image(levels[lev],
00172                                                      masks[lev],
00173                                                      parent_img,
00174                                                      parent_mask,
00175                                                      scale,
00176                                                      roots);
00177     brip_quadtree_utils<T>::connect_children(roots,scale, prev);
00178 
00179     prev = roots;
00180     scale = scale*2;
00181   }
00182 }
00183 
00184 template <class T>
00185 void brip_quadtree_utils<T>::
00186 print_node( brip_quadtree_node_base_sptr const& node,
00187             vcl_ostream& os,
00188             vcl_string indent)
00189 {
00190   //cast the node to the type
00191   brip_quadtree_node<T>* nt = dynamic_cast<brip_quadtree_node<T>* >(node.ptr());
00192   if (!nt)
00193     return;
00194   unsigned iul = 0, jul = 0, ilr = 0, jlr = 0;
00195   nt->region(iul, jul, ilr, jlr);
00196   // base case, no children
00197   if (nt->n_children()==0){
00198     os << indent << "leaf:(" << iul << ' ' << jul << ")("
00199        << ilr << ' ' << jlr << "):data= ";
00200     if (nt->data_valid())
00201       os << nt->data() << '\n';
00202     else
00203       os << "###\n";
00204     return;
00205   }
00206   os << indent << "node:(" << iul << ' ' << jul << ")("
00207      << ilr << ' ' << jlr << "):data= ";
00208   if (nt->data_valid())
00209     os << nt->data() << '\n';
00210   else
00211     os << "###\n";
00212   vcl_string ind = indent + "  ";
00213   for (unsigned i = 0; i<2; ++i)
00214     for (unsigned j = 0; j<2; ++j)
00215       if (nt->child(i,j))
00216         brip_quadtree_utils<T>::print_node(nt->child(i,j),
00217                                            os,
00218                                            ind);
00219 }
00220 
00221 #undef BRIP_QUADTREE_UTILS_INSTANTIATE
00222 #define BRIP_QUADTREE_UTILS_INSTANTIATE(T) \
00223 template class brip_quadtree_utils<T >
00224 
00225 #endif // brip_quadtree_utils_txx_