00001 #ifndef brip_quadtree_utils_txx_
00002 #define brip_quadtree_utils_txx_
00003 #include "brip_quadtree_utils.h"
00004
00005
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
00033
00034 brip_quadtree_utils<T>::fill_image_region(node, img);
00035
00036 if (!node->n_children())
00037 return;
00038
00039
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
00055
00056
00057
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
00073 unsigned iul = i*scale, jul = j*scale;
00074
00075 unsigned ilr = iul + 2*scale -1;
00076 unsigned jlr = jul + 2*scale -1;
00077
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
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
00092 unsigned iulc = c*scale, julc = r*scale;
00093
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
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
00124 unsigned iul = c*scale, jul = r*scale;
00125
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
00145
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
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
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_