vil_transform.h
Go to the documentation of this file.
1 // This is core/vil/vil_transform.h
2 #ifndef vil_transform_h_
3 #define vil_transform_h_
4 //:
5 // \file
6 // \brief STL algorithm like methods.
7 // \author Ian Scott.
8 
9 #include <cassert>
10 #ifdef _MSC_VER
11 # include <vcl_msvc_warnings.h>
12 #endif
13 #include <vil/vil_image_view.h>
14 
15 //: Apply a unary operation to each pixel in image.
16 // \param functor should take a value of type T and return same type
17 // \relatesalso vil_image_view
18 template <class T, class F >
19 inline void vil_transform(vil_image_view<T >& image, F functor)
20 {
21  const unsigned ni = image.ni(), nj= image.nj(), np = image.nplanes();
22 
23  std::ptrdiff_t istep=image.istep(),jstep=image.jstep(),pstep = image.planestep();
24  T* plane = image.top_left_ptr();
25 
26  if (istep==1)
27  {
28  // Optimise special case
29  for (unsigned p=0;p<np;++p,plane += pstep)
30  {
31  T* row = plane;
32  for (unsigned j=0;j<nj;++j,row += jstep)
33  {
34  T *pixel = row, *end_row = row+ni;
35  for (;pixel!=end_row;++pixel) *pixel = functor(*pixel);
36  }
37  }
38  }
39  else
40  if (jstep==1)
41  {
42  // Optimise special case
43  for (unsigned p=0;p<np;++p,plane += pstep)
44  {
45  T* col = plane;
46  for (unsigned i=0;i<ni;++i,col += istep)
47  {
48  T *pixel = col, *end_col=col+nj;
49  for (;pixel!=end_col;++pixel) *pixel = functor(*pixel);
50  }
51  }
52  }
53  else
54  {
55  // General case
56  for (unsigned p=0;p<np;++p,plane += pstep)
57  {
58  T* row = plane;
59  for (unsigned j=0;j<nj;++j,row += jstep)
60  {
61  T* pixel = row;
62  for (unsigned i=0;i<ni;++i,pixel+=istep)
63  *pixel = functor(*pixel);
64  }
65  }
66  }
67 }
68 
69 
70 //: Apply a unary operation to each pixel in src to get dest.
71 // \param functor should take a value of type inP, and return a value of type outP
72 // \relatesalso vil_image_view
73 template <class inP, class outP, class Op >
74 inline void vil_transform(const vil_image_view<inP >&src, vil_image_view<outP >&dest, Op functor)
75 {
76  const unsigned ni = src.ni(), nj= src.nj(), np = src.nplanes();
77 
78  dest.set_size(ni, nj, np);
79 
80  // Optimise special case;
81  if (dest.istep()==1 && src.istep()==1)
82  {
83  for (unsigned p = 0; p < np; ++p)
84  for (unsigned j = 0; j < nj; ++j)
85  {
86  const inP* src_row = &src(0,j,p);
87  outP* dest_row = &dest(0,j,p);
88  for (unsigned i = 0; i < ni; ++i)
89  dest_row[i] = functor(src_row[i]);
90  }
91  return;
92  }
93 
94  for (unsigned p = 0; p < np; ++p)
95  for (unsigned j = 0; j < nj; ++j)
96  for (unsigned i = 0; i < ni; ++i)
97  dest(i,j,p) = functor(src(i,j,p));
98 }
99 
100 //: Apply a binary function to each pixel in src and dest that modifies dest.
101 // \param functor should take two parameters (inP src, outP &dest);
102 // \relatesalso vil_image_view
103 template <class inP, class outP, class Op >
104 inline void vil_transform2(const vil_image_view<inP >&src, vil_image_view<outP >&dest, Op functor)
105 {
106  const unsigned ni = src.ni(), nj= src.nj(), np = src.nplanes();
107 
108  dest.set_size(ni, nj, np);
109 
110  // Optimise special case;
111  if (dest.istep()==1 && src.istep()==1)
112  {
113  for (unsigned p = 0; p < np; ++p)
114  for (unsigned j = 0; j < nj; ++j)
115  {
116  const inP* src_row = &src(0,j,p);
117  outP* dest_row = &dest(0,j,p);
118  for (unsigned i = 0; i < ni; ++i)
119  functor(src_row[i],dest_row[i]);
120  }
121  return;
122  }
123 
124  for (unsigned p = 0; p < np; ++p)
125  for (unsigned j = 0; j < nj; ++j)
126  for (unsigned i = 0; i < ni; ++i)
127  functor(src(i,j,p), dest(i,j,p));
128 }
129 
130 
131 //: Apply a binary operation to each pixel in srcA and srcB to get dest.
132 // \relatesalso vil_image_view
133 template <class inA, class inB, class outP, class BinOp >
134 inline void vil_transform(const vil_image_view<inA >&srcA,
135  const vil_image_view<inB >&srcB,
137  BinOp functor)
138 {
139  assert(srcB.ni() == srcA.ni() && srcA.nj() == srcB.nj() && srcA.nplanes() == srcB.nplanes());
140  dest.set_size(srcA.ni(), srcA.nj(), srcA.nplanes());
141  for (unsigned p = 0; p < srcA.nplanes(); ++p)
142  for (unsigned j = 0; j < srcA.nj(); ++j)
143  for (unsigned i = 0; i < srcA.ni(); ++i)
144  dest(i,j,p) = functor(srcA(i,j,p),srcB(i,j,p));
145 }
146 
147 //: Apply a binary operation to each pixel in srcA and srcB to get dest.
148 // non-const dest version, assumes dest is already correct size.
149 // \relatesalso vil_image_view
150 template <class inA, class inB, class outP, class BinOp >
151 inline void vil_transform(const vil_image_view<inA >&srcA,
152  const vil_image_view<inB >&srcB,
153  const vil_image_view<outP >&dest,
154  BinOp functor)
155 {
156  assert(dest.ni() == srcA.ni() && srcA.nj() == dest.nj() && srcA.nplanes() == dest.nplanes());
157  assert(srcB.ni() == srcA.ni() && srcA.nj() == srcB.nj() && srcA.nplanes() == srcB.nplanes());
158  vil_image_view<outP >& nc_dest = const_cast<vil_image_view<outP >&>(dest);
159  for (unsigned p = 0; p < srcA.nplanes(); ++p)
160  for (unsigned j = 0; j < srcA.nj(); ++j)
161  for (unsigned i = 0; i < srcA.ni(); ++i)
162  nc_dest(i,j,p) = functor(srcA(i,j,p),srcB(i,j,p));
163 }
164 
165 
166 #endif // vil_transform_h_
void vil_transform(vil_image_view< T > &image, F functor)
Apply a unary operation to each pixel in image.
Definition: vil_transform.h:19
Concrete view of image data of type T held in memory.
Definition: vil_fwd.h:13
void set_size(unsigned ni, unsigned nj) override
resize current planes to ni x nj.
void vil_transform2(const vil_image_view< inP > &src, vil_image_view< outP > &dest, Op functor)
Apply a binary function to each pixel in src and dest that modifies dest.
std::ptrdiff_t jstep() const
Add this to your pixel pointer to get next j pixel.
unsigned ni() const
Width.
unsigned nj() const
Height.
std::ptrdiff_t planestep() const
Add this to your pixel pointer to get pixel on next plane.
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.
std::ptrdiff_t istep() const
Add this to your pixel pointer to get next i pixel.