MRaster lib 22.0.0.0
Image Processing Library
Loading...
Searching...
No Matches
ramCanvasPixelFilters.hpp
Go to the documentation of this file.
1#ifndef MJR_INCLUDE_rcPixelFilters
2
3////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4// Put everything in the mjr namespace
5namespace mjr {
6 /** @brief Namespace for ramCanvas Pixel Filters.
7
8 mjr::ramCanvasPixelFilter objects attach to, and override, the minimal pixel access interface of another object. The idea is to provide an alternate
9 pixel access interface that may modify the data in transit. In this way they mjr::ramCanvasPixelFilter objects provide an alternate "view" of the pixel
10 data. For example mjr::ramCanvasTpl::writeTIFFfile() can use mjr::ramCanvasPixelFilter::RGBbyte to write a 24-bit RGB image from a source
11 mjr::ramCanvasTpl object containing floating point channels. Note that mjr::ramCanvasPixelFilter objects themselves provide a minimal pixel access
12 interface, and thus mjr::ramCanvasPixelFilter objects can be attached to other mjr::ramCanvasPixelFilter objects allowing one to chain together a list of
13 pixel data filters.
14
15 The minimal pixel access interface for a mjr::ramCanvasTpl-like object consists of the following seven members:
16
17 - isIntAxOrientationNaturalX()
18 - isIntAxOrientationNaturalY()
19 - getNumPixX()
20 - getNumPixY()
21 - getPxColorNC(x, y)
22 - colorType
23 - coordIntType
24
25 It is important to remember that mjr::ramCanvasPixelFilter objects can modify not just the pixel data but the size of a mjr::ramCanvasTpl object. For
26 example, mjr::ramCanvasPixelFilter::ScaleDownMean can be used to virtually resize a mjr::ramCanvasTpl object! For this reason it is important to use the
27 getNumPixX() and getNumPixY() methods when working with pixel data.
28
29 Note the pixel interface provided by mjr::ramCanvasPixelFilter objects might be described with the adjectives: *minimal*, *fast*, and *unsafe*! The
30 interface is unsafe in that it provides access to getPxColorNC() and *not* getPxColor(). That means no bounds checks are made on pixel coordinates. In
31 short, mjr::ramCanvasPixelFilter objects are intended to be consumed by code that has the necessary bounds checks built in. Keep this in mind if you use
32 them for something else!
33 */
34 namespace ramCanvasPixelFilter {
35 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
36 /** @name ramCanvasTpl pixel filter classes. */
37 //@{
38 //--------------------------------------------------------------------------------------------------------------------------------------------------------
39 /** An incomplete class (no getPxColorNC method) that provides a nice base for homogeniouss pixel filters
40 \tparam sourceT The type of the ram canvas to filter. */
41 template<class sourceT>
43 public:
44 sourceT& attachedRC;
45 FixGeomBase(sourceT& aRC) : attachedRC(aRC) { }
46 typedef typename sourceT::coordIntType coordIntType;
47 inline bool isIntAxOrientationNaturalX() { return attachedRC.isIntAxOrientationNaturalX(); }
48 inline bool isIntAxOrientationNaturalY() { return attachedRC.isIntAxOrientationNaturalY(); }
49 inline coordIntType getNumPixX() { return attachedRC.getNumPixX(); }
50 inline coordIntType getNumPixY() { return attachedRC.getNumPixY(); }
51 //virtual colorType getPxColorNC(coordIntType x, coordIntType y) = 0;
52 };
53 //--------------------------------------------------------------------------------------------------------------------------------------------------------
54 /** Identity filter -- i.e. NOP. */
55 template<class sourceT>
56 class Identity : public FixGeomBase<sourceT> {
57 public:
58 Identity(sourceT& aRC) : FixGeomBase<sourceT>(aRC) { }
59 typedef typename sourceT::colorType colorType;
60 typedef typename sourceT::coordIntType coordIntType;
62 };
63 //--------------------------------------------------------------------------------------------------------------------------------------------------------
64 /** Convert to an RGB color image with 8-bit integer channels. */
65 template<class sourceT>
66 class RGBbyte : public FixGeomBase<sourceT> {
67 public:
68 RGBbyte(sourceT& aRC) : FixGeomBase<sourceT>(aRC) { }
69 typedef typename sourceT::colorType::colConRGBbyte colorType;
70 typedef typename sourceT::coordIntType coordIntType;
71 inline colorType getPxColorNC(coordIntType x, coordIntType y) { return FixGeomBase<sourceT>::attachedRC.getPxColorNC(x, y).getColConRGB_byte(); }
72 };
73 //--------------------------------------------------------------------------------------------------------------------------------------------------------
74 /** Convert to an RGBA color image with 8-bit integer channels. */
75 template<class sourceT>
76 class RGBAbyte : public FixGeomBase<sourceT> {
77 public:
78 RGBAbyte(sourceT& aRC) : FixGeomBase<sourceT>(aRC) { }
79 typedef typename sourceT::colorType::colConRGBAbyte colorType;
80 typedef typename sourceT::coordIntType coordIntType;
81 inline colorType getPxColorNC(coordIntType x, coordIntType y) { return FixGeomBase<sourceT>::attachedRC.getPxColorNC(x, y).getColConRGBA_byte(); }
82 };
83 //--------------------------------------------------------------------------------------------------------------------------------------------------------
84 /** Convert to an RGB color image with 64-bit floating point channels. */
85 template<class sourceT>
86 class RGBdbl : public FixGeomBase<sourceT> {
87 public:
88 RGBdbl(sourceT& aRC) : FixGeomBase<sourceT>(aRC) { }
89 typedef typename sourceT::colorType::colConRGBdbl colorType;
90 typedef typename sourceT::coordIntType coordIntType;
91 inline colorType getPxColorNC(coordIntType x, coordIntType y) { return FixGeomBase<sourceT>::attachedRC.getPxColorNC(x, y).getColConRGB_dbl(); }
92 };
93 //--------------------------------------------------------------------------------------------------------------------------------------------------------
94 /** Convert to an RGBA color image with 64-bit floating point channels. */
95 template<class sourceT>
96 class RGBAdbl : public FixGeomBase<sourceT> {
97 public:
98 RGBAdbl(sourceT& aRC) : FixGeomBase<sourceT>(aRC) { }
99 typedef typename sourceT::colorType::colConRGBAdbl colorType;
100 typedef typename sourceT::coordIntType coordIntType;
101 inline colorType getPxColorNC(coordIntType x, coordIntType y) { return FixGeomBase<sourceT>::attachedRC.getPxColorNC(x, y).getColConRGBA_dbl(); }
102 };
103 //--------------------------------------------------------------------------------------------------------------------------------------------------------
104 /** Monochrome transformation using colorT::intensityScaled(). */
105 template<class sourceT, class outColorChanT>
106 class MonoIntensity : public FixGeomBase<sourceT> {
107 public:
108 MonoIntensity(sourceT& aRC) : FixGeomBase<sourceT>(aRC) { }
110 typedef typename sourceT::coordIntType coordIntType;
112 return static_cast<outColorChanT>(FixGeomBase<sourceT>::attachedRC.getPxColorNC(x, y).intensityScaled() * colorType::maxChanVal);
113 }
114 };
115 //--------------------------------------------------------------------------------------------------------------------------------------------------------
116 /** Colorize by applying a color scheme to a single channel automatically mapping max channel value to max color scheme index.
117 \tparam outColorT Color type to return.
118 \tparam chan Channel to use from the input image. */
119 template<class sourceT, class outColorT, class colorScheme, int chan = 0>
120 requires(std::same_as<outColorT, decltype(colorScheme::c(1))> && (chan>=0) && (chan<outColorT::channelCount))
121 class ColorSchemeOnChan : public FixGeomBase<sourceT> {
122 public:
123 ColorSchemeOnChan(sourceT& aRC) : FixGeomBase<sourceT>(aRC) { }
124 typedef outColorT colorType;
125 typedef typename sourceT::coordIntType coordIntType;
127 if constexpr (sourceT::colorType::chanIsInt) {
128 return colorScheme::c(static_cast<outColorT::csIntType>(mjr::math::linm::gen_map(static_cast<sourceT::colorType::channelArithSDPType>(FixGeomBase<sourceT>::attachedRC.getPxColorNC(x, y).getChan(chan)),
129 static_cast<sourceT::colorType::channelArithSDPType>(sourceT::colorType::minChanVal),
130 static_cast<sourceT::colorType::channelArithSDPType>(sourceT::colorType::maxChanVal),
131 static_cast<sourceT::colorType::channelArithSDPType>(0),
132 static_cast<sourceT::colorType::channelArithSDPType>(colorScheme::numC - 1))));
133 } else {
134 return colorScheme::c(static_cast<outColorT::csFltType>(FixGeomBase<sourceT>::attachedRC.getPxColorNC(x, y).getChan(chan)));
135 }
136 }
137 };
138 //--------------------------------------------------------------------------------------------------------------------------------------------------------
139 /** Transform an image with a pixel function.
140 \tparam outColorT Color type to return.
141 \tparam chan Channel to use from the input image. */
142 template<class sourceT, class outColorT = sourceT::colorType>
143 class FuncHomoTransform : public FixGeomBase<sourceT> {
144 public:
145 typedef std::function<outColorT(typename sourceT::colorType)> ctf_t;
146 private:
148 public:
149 FuncHomoTransform(sourceT& aRC, ctf_t colorTransformFunction) : FixGeomBase<sourceT>(aRC), ctf(colorTransformFunction) { }
150 typedef outColorT colorType;
151 typedef typename sourceT::coordIntType coordIntType;
153 };
154 //--------------------------------------------------------------------------------------------------------------------------------------------------------
155 /** Scale down a canvis using a method similar to ramCanvasTpl::scaleDownMean(). */
156 template<class sourceT, int factor>
158 public:
159 sourceT& attachedRC;
160 ScaleDownMean(sourceT& aRC) : attachedRC(aRC) { }
161 typedef typename sourceT::colorType colorType;
162 typedef typename sourceT::coordIntType coordIntType;
163 inline bool isIntAxOrientationNaturalX() { return attachedRC.isIntAxOrientationNaturalX(); }
164 inline bool isIntAxOrientationNaturalY() { return attachedRC.isIntAxOrientationNaturalY(); }
165 inline coordIntType getNumPixX() { return attachedRC.getNumPixX() / factor; }
166 inline coordIntType getNumPixY() { return attachedRC.getNumPixY() / factor; }
168 coordIntType x0 = x * factor;
169 coordIntType y0 = y * factor;
170 colorType retColor(static_cast<colorType::channelType>(0));
171 for(int c=0; c<colorType::channelCount; c++) {
172 typename colorType::channelArithSPType sum = static_cast<colorType::channelArithSPType>(0);
173 for(coordIntType yi=0; yi<factor; yi++) {
174 for(coordIntType xi=0; xi<factor; xi++) {
175 sum += attachedRC.getPxColorNC(xi+x0, yi+y0).getChanNC(c);
176 }
177 }
178 retColor.setChanNC(c, static_cast<colorType::channelType>(sum/factor/factor));
179 }
180 return retColor;
181 }
182 };
183 //--------------------------------------------------------------------------------------------------------------------------------------------------------
184 /** Rotate image 90 degrees clockwise. */
185 template<class sourceT>
187 public:
188 sourceT& attachedRC;
189 Rotate90CW(sourceT& aRC) : attachedRC(aRC) { }
190 typedef typename sourceT::colorType colorType;
191 typedef typename sourceT::coordIntType coordIntType;
192 inline bool isIntAxOrientationNaturalX() { return attachedRC.isIntAxOrientationNaturalX(); }
193 inline bool isIntAxOrientationNaturalY() { return attachedRC.isIntAxOrientationNaturalY(); }
194 inline coordIntType getNumPixX() { return attachedRC.getNumPixY(); }
195 inline coordIntType getNumPixY() { return attachedRC.getNumPixX(); }
196 inline colorType getPxColorNC(coordIntType x, coordIntType y) { return attachedRC.getPxColorNC((attachedRC.getNumPixY()-1)-y, x); }
197 };
198 //@}
199 }
200} // end namespace mjr
201
202#define MJR_INCLUDE_rcPixelFilters
203#endif
Template Class used to house colors for ramCanvas objects.
static constexpr clrChanT maxChanVal
maximum value for a channel
Colorize by applying a color scheme to a single channel automatically mapping max channel value to ma...
colorType getPxColorNC(coordIntType x, coordIntType y)
An incomplete class (no getPxColorNC method) that provides a nice base for homogeniouss pixel filters...
Transform an image with a pixel function.
std::function< outColorT(typename sourceT::colorType)> ctf_t
colorType getPxColorNC(coordIntType x, coordIntType y)
FuncHomoTransform(sourceT &aRC, ctf_t colorTransformFunction)
colorType getPxColorNC(coordIntType x, coordIntType y)
Monochrome transformation using colorT::intensityScaled().
colorType getPxColorNC(coordIntType x, coordIntType y)
Convert to an RGBA color image with 8-bit integer channels.
sourceT::colorType::colConRGBAbyte colorType
colorType getPxColorNC(coordIntType x, coordIntType y)
Convert to an RGBA color image with 64-bit floating point channels.
colorType getPxColorNC(coordIntType x, coordIntType y)
sourceT::colorType::colConRGBAdbl colorType
Convert to an RGB color image with 8-bit integer channels.
colorType getPxColorNC(coordIntType x, coordIntType y)
sourceT::colorType::colConRGBbyte colorType
Convert to an RGB color image with 64-bit floating point channels.
sourceT::colorType::colConRGBdbl colorType
colorType getPxColorNC(coordIntType x, coordIntType y)
Rotate image 90 degrees clockwise.
colorType getPxColorNC(coordIntType x, coordIntType y)
Scale down a canvis using a method similar to ramCanvasTpl::scaleDownMean().
colorType getPxColorNC(coordIntType x, coordIntType y)