vil_fill.h
Go to the documentation of this file.
1 // This is core/vil/vil_fill.h
2 #ifndef vil_fill_h_
3 #define vil_fill_h_
4 //:
5 // \file
6 // \brief Various functions for manipulating image views
7 // \author Tim Cootes - Manchester
8 
9 #include <algorithm>
10 #include <cassert>
11 #include <vil/vil_image_view.h>
12 #ifdef _MSC_VER
13 # include <vcl_msvc_warnings.h>
14 #endif
15 
16 //: Fill view with given value
17 // O(size).
18 // \relatesalso vil_image_view
19 template<class T>
20 void vil_fill(vil_image_view<T>& view, T value)
21 {
22  if (view.is_contiguous())
23  std::fill(view.begin(), view.end(), value);
24 
25  unsigned ni = view.ni();
26  std::ptrdiff_t istep=view.istep();
27  unsigned nj = view.nj();
28  std::ptrdiff_t jstep=view.jstep();
29  unsigned np = view.nplanes();
30  std::ptrdiff_t pstep = view.planestep();
31 
32  T* plane = view.top_left_ptr();
33  for (unsigned p=0;p<np;++p,plane += pstep)
34  {
35  T* row = plane;
36  for (unsigned j=0;j<nj;++j,row += jstep)
37  {
38  T* pixel = row;
39  for (unsigned i=0;i<ni;++i,pixel+=istep) *pixel=value;
40  }
41  }
42 }
43 
44 //: Fill data[i*step] (i=0..n-1) with given value
45 // \sa vil_fill_line(vil_image_view<T>)
46 template<class T>
47 void vil_fill_line(T* data, unsigned n, std::ptrdiff_t step, T value)
48 {
49  T* end_data = data + n*step;
50  while (data!=end_data) { *data=value; data+=step; }
51 }
52 
53 
54 //: Fill line from (ai,aj) to (bi,bj) using Bresenham's algorithm.
55 // Only modifies first plane.
56 // \relatesalso vil_image_view
57 template<class T>
59  int ai, int aj, int bi, int bj,
60  T value)
61 {
62  if (ai == bi && aj==bj)
63  {
64  if (im.in_range(ai, aj)) im(ai,aj) = value;
65  return;
66  }
67 
68  int d, x, y, xinc, yinc, incr1, incr2;
69 
70  int dx = bi-ai;
71  int dy = bj-aj;
72  if (dy<0)
73  {
74  dy=-dy;
75  yinc=-1;
76  }
77  else
78  yinc=1;
79 
80  if (dx<0)
81  {
82  dx=-dx;
83  xinc=-1;
84  }
85  else
86  xinc=1;
87 
88  if (im.in_range(ai, aj)) im(ai, aj)=value;
89  x=ai;
90  y=aj;
91  if (dy<=dx)
92  {
93  d=(dy<<1)-dx;
94  incr1=dy<<1;
95  incr2=-((dx-dy)<<1);
96  while (x!=bi)
97  {
98  x+=xinc;
99  if (d<0)
100  d+=incr1;
101  else
102  {
103  y+=yinc;
104  d+=incr2;
105  }
106  if (im.in_range(x, y)) im(x, y)=value;
107  }
108  }
109  else
110  {
111  d=(dx<<1)-dy;
112  incr1=dx<<1;
113  incr2=-((dy-dx)<<1);
114  while (y!=bj)
115  {
116  y+=yinc;
117  if (d<0)
118  d+=incr1;
119  else
120  {
121  x+=xinc;
122  d+=incr2;
123  }
124  if (im.in_range(x, y)) im(x, y)=value;
125  }
126  }
127 }
128 
129 //: Fill row j in view with given value
130 // O(ni).
131 // \relatesalso vil_image_view
132 template<class T>
133 void vil_fill_row(vil_image_view<T>& view, unsigned j, T value)
134 {
135  unsigned ni = view.ni(); std::ptrdiff_t istep=view.istep();
136  assert(j<view.nj()); std::ptrdiff_t jstep=view.jstep();
137  unsigned np = view.nplanes(); std::ptrdiff_t pstep=view.planestep();
138 
139  T* row = view.top_left_ptr() + j*jstep;
140  for (unsigned p=0;p<np;++p,row += pstep)
141  vil_fill_line(row,ni,istep,value);
142 }
143 
144 //: Fill column i in view with given value
145 // O(nj).
146 // \relatesalso vil_image_view
147 template<class T>
148 void vil_fill_col(vil_image_view<T>& view, unsigned i, T value)
149 {
150  assert(i<view.ni()); std::ptrdiff_t istep=view.istep();
151  unsigned nj = view.nj(); std::ptrdiff_t jstep=view.jstep();
152  unsigned np = view.nplanes(); std::ptrdiff_t pstep=view.planestep();
153 
154  T* col_top = view.top_left_ptr() + i*istep;
155  for (unsigned p=0;p<np;++p,col_top += pstep)
156  vil_fill_line(col_top,nj,jstep,value);
157 }
158 
159 //: Writes given value into each pixel of image under the elements of the mask set to b
160 // If mask.nplanes()==1 then the same mask is applied to every image plane, otherwise
161 // there must be the same number of mask planes as image planes.
162 // \relatesalso vil_image_view
163 template<class srcT>
164 inline
166  const vil_image_view<bool>& mask,
167  srcT value, bool b=true)
168 {
169  unsigned ni = image.ni(), nj = image.nj(), np = image.nplanes();
170  assert(ni==mask.ni() && nj==mask.nj());
171  assert(mask.nplanes()==1 || mask.nplanes() ==np);
172 
173  std::ptrdiff_t istepA=image.istep(),jstepA=image.jstep(),pstepA = image.planestep();
174  std::ptrdiff_t istepB=mask.istep(),jstepB=mask.jstep(),pstepB = mask.planestep();
175 
176  // If only one mask plane, apply to all image planes
177  // Setting pstepB to 0 ensures that the same mask is used for each pass
178  if (mask.nplanes()==1) pstepB=0;
179 
180  srcT* planeA = image.top_left_ptr();
181  const bool* planeB = mask.top_left_ptr();
182  for (unsigned p=0;p<np;++p,planeA += pstepA,planeB += pstepB)
183  {
184  srcT* rowA = planeA;
185  const bool* rowB = planeB;
186  for (unsigned j=0;j<nj;++j,rowA += jstepA,rowB += jstepB)
187  {
188  srcT* pixelA = rowA;
189  const bool* pixelB = rowB;
190  for (unsigned i=0;i<ni;++i,pixelA+=istepA,pixelB+=istepB)
191  if (*pixelB==b) *pixelA=value;
192  }
193  }
194 }
195 
196 //: Fills pixels in disk with centre (ci,cj), radius r, with given value
197 // Fills all planes of image with the value.
198 // \relatesalso vil_image_view
199 template<class T>
200 inline
201 void vil_fill_disk(vil_image_view<T>& image, double ci, double cj, double r, T value)
202 {
203  unsigned ilo = std::max(0,int(ci-r));
204  unsigned ihi = std::max(0,std::min(int(image.ni()-1),int(ci+r+1.0)));
205  unsigned jlo = std::max(0,int(cj-r));
206  unsigned jhi = std::max(0,std::min(int(image.nj()-1),int(cj+r+1.0)));
207 
208  double r2 = r*r;
209  for (unsigned j=jlo;j<=jhi;++j)
210  {
211  double t2 = r2 - (j-cj)*(j-cj);
212  for (unsigned i=ilo;i<=ihi;++i)
213  {
214  if ((i-ci)*(i-ci)<t2)
215  {
216  for (unsigned k=0;k<image.nplanes();++k) image(i,j,k)=value;
217  }
218  }
219  }
220 }
221 
222 #endif // vil_fill_h_
Concrete view of image data of type T held in memory.
Definition: vil_fwd.h:13
bool is_contiguous() const
True if data all in one unbroken block and top_left_ptr() is lowest data address.
std::ptrdiff_t jstep() const
Add this to your pixel pointer to get next j pixel.
void vil_fill_col(vil_image_view< T > &view, unsigned i, T value)
Fill column i in view with given value.
Definition: vil_fill.h:148
bool in_range(int i, int j) const
Return true if (i,j) is a valid index into this buffer.
unsigned ni() const
Width.
iterator end()
unsigned nj() const
Height.
void vil_fill_line(vil_image_view< T > &im, int ai, int aj, int bi, int bj, T value)
Fill line from (ai,aj) to (bi,bj) using Bresenham's algorithm.
Definition: vil_fill.h:58
std::ptrdiff_t planestep() const
Add this to your pixel pointer to get pixel on next plane.
iterator begin()
void vil_fill_disk(vil_image_view< T > &image, double ci, double cj, double r, T value)
Fills pixels in disk with centre (ci,cj), radius r, with given value.
Definition: vil_fill.h:201
A base class reference-counting view of some image data.
T * top_left_ptr()
Pointer to the first (top left in plane 0) pixel.
unsigned nplanes() const
Number of planes.
void vil_fill_mask(vil_image_view< srcT > &image, const vil_image_view< bool > &mask, srcT value, bool b=true)
Writes given value into each pixel of image under the elements of the mask set to b.
Definition: vil_fill.h:165
std::ptrdiff_t istep() const
Add this to your pixel pointer to get next i pixel.
void vil_fill_row(vil_image_view< T > &view, unsigned j, T value)
Fill row j in view with given value.
Definition: vil_fill.h:133
void vil_fill(vil_image_view< T > &view, T value)
Fill view with given value.
Definition: vil_fill.h:20