core/vil/algo/vil_structuring_element.cxx
Go to the documentation of this file.
00001 // This is core/vil/algo/vil_structuring_element.cxx
00002 #include "vil_structuring_element.h"
00003 //:
00004 // \file
00005 // \brief Structuring element for morphology represented as a list of non-zero pixels
00006 // \author Tim Cootes
00007 
00008 #include <vcl_cassert.h>
00009 #include <vcl_iostream.h>
00010 
00011 //: Define elements { (p_i[k],p_j[k]) }
00012 void vil_structuring_element::set(const vcl_vector<int>& v_p_i,const vcl_vector<int>& v_p_j)
00013 {
00014   assert(v_p_i.size()==v_p_j.size());
00015   assert(v_p_i.size()>0);
00016   p_i_ = v_p_i;
00017   p_j_ = v_p_j;
00018 
00019   max_i_=min_i_ = v_p_i[0];
00020   max_j_=min_j_ = v_p_j[0];
00021   for (unsigned int k=1;k<v_p_i.size();++k)
00022   {
00023     if (v_p_i[k]<min_i_) min_i_=v_p_i[k];
00024     else if (v_p_i[k]>max_i_) max_i_=v_p_i[k];
00025 
00026     if (v_p_j[k]<min_j_) min_j_=v_p_j[k];
00027     else if (v_p_j[k]>max_j_) max_j_=v_p_j[k];
00028   }
00029 }
00030 
00031 //: Set to disk of radius r
00032 //  Select pixels in disk s.t. x^x+y^y<r^r
00033 void vil_structuring_element::set_to_disk(double r)
00034 {
00035   vcl_vector<int> px,py;
00036   double r2 = r*r;
00037   int r0 = int(r+1);
00038   for (int j=-r0;j<=r0;++j)
00039     for (int i=-r0;i<=r0;++i)
00040       if (i*i+j*j<r2) { px.push_back(i); py.push_back(j); }
00041   set(px,py);
00042 }
00043 
00044 //: Set to line along i (ilo,0)..(ihi,0)
00045 void vil_structuring_element::set_to_line_i(int ilo, int ihi)
00046 {
00047   p_i_.resize(1+ihi-ilo);
00048   p_j_.resize(1+ihi-ilo);
00049   for (int i = ilo;i<=ihi;++i)
00050   {
00051     p_i_[i-ilo]=i; p_j_[i-ilo]=0;
00052   }
00053 
00054   min_i_ = ilo; max_i_ = ihi;
00055   min_j_ = 0;   max_j_ = 0;
00056 }
00057 
00058 //: Set to line along j (jlo,0)..(jhi,0)
00059 void vil_structuring_element::set_to_line_j(int jlo, int jhi)
00060 {
00061   p_i_.resize(1+jhi-jlo);
00062   p_j_.resize(1+jhi-jlo);
00063   for (int j = jlo;j<=jhi;++j)
00064   {
00065     p_i_[j-jlo]=0; p_j_[j-jlo]=j;
00066   }
00067 
00068   min_i_ = 0;   max_i_ = 0;
00069   min_j_ = jlo; max_j_ = jhi;
00070 }
00071 
00072 //: Write details to stream
00073 vcl_ostream& operator<<(vcl_ostream& os, const vil_structuring_element& element)
00074 {
00075   os<<"Bounds ["
00076     <<element.min_i()<<','<<element.max_i()<<"]["
00077     <<element.min_j()<<','<<element.max_j()<<"] Points: ";
00078   for (unsigned int k=0;k<element.p_i().size();++k)
00079     os<<'('<<element.p_i()[k]<<','<<element.p_j()[k]<<") ";
00080   return os;
00081 }
00082 
00083 //: Generate a list of offsets for use on image with istep,jstep
00084 //  Gives an efficient way of looping through all the pixels in the structuring element
00085 void vil_compute_offsets(vcl_vector<vcl_ptrdiff_t>& offset, const vil_structuring_element& element,
00086                          vcl_ptrdiff_t istep, vcl_ptrdiff_t jstep)
00087 {
00088   unsigned n = element.p_i().size();
00089   offset.resize(n);
00090   for (unsigned int k=0;k<n;++k)
00091     offset[k] = static_cast<vcl_ptrdiff_t>(element.p_i()[k]*istep +  element.p_j()[k]*jstep);
00092 }
00093