Loading...
Searching...
No Matches
ImageCodebook.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30*/
31#ifndef DRAIN_CODEBOOK
32#define DRAIN_CODEBOOK
33
34
35#include <drain/Log.h>
36#include <ostream>
37#include <vector>
38#include <map>
39
40#include "drain/util/ValueScaling.h"
41#include "drain/util/LookUp.h"
42
43namespace drain
44{
45
47
51template <class T>
52class ImageCodeMap : public std::map<double,T> { // : public std::vector<T> {
53
54public:
55
56 typedef std::map<double,T> cont_t;
57 typedef typename cont_t::key_type key_t;
58 typedef typename cont_t::value_type entry_t;
59
62
63 // Utility for initializer_list based inits: the threshold values are read in parallel.
64 typedef typename std::list<entry_t> list_t;
65
66
68 //ImageCodeMap(size_t n=0, const T & value=T()): cont_t(n, value), separator(0) {
69 ImageCodeMap() : separator(0) {
70 };
71
72
73 ImageCodeMap(std::initializer_list<entry_t> l) : cont_t(l), separator(0) {
74 };
75
76
78 // ImageCodeMap(const cont_t & v): cont_t(v), separator(0) {
79 ImageCodeMap(const cont_t & map): separator(0) { // COPY?
80 };
81
82
83
84 mutable
85 lookup_t lookUp;
86
88
95 lookup_t & createLookUp(const std::type_info & type, const ValueScaling & scaling) const;
96 // inline
97 typename cont_t::const_iterator retrieve(double d) const {
98
99 typename cont_t::const_iterator it = this->begin();
100 typename cont_t::const_iterator rit = it; // result
101
102 while (it != this->end()){
103 if (it->first > d)
104 return rit;
105 rit = it;
106 ++it;
107 }
108
109 return rit; // may be invalid
110
111 }
112
113 // inline
114 typename cont_t::iterator retrieve(double d) {
115
116 typename cont_t::iterator it = this->begin();
117 typename cont_t::iterator rit = it;
118
119 while (it != this->end()){
120 if (it->first > d)
121 return rit;
122 rit = it;
123 ++it;
124 }
125
126 return rit; // may be invalid
127
128 }
129
130
131
132
134 /*
135 * \param equal - typically =, :, or -
136 * \param start - typically hyphen or leading parenthesis (, {, [
137 * \param end - typically hyphen or trailing parenthesis ), }, [
138 * \param separator - typically comma or semicolon
139 */
140
141 // ValueScaling scaling; more like property of image
142
143 char separator;
144};
145
146/*
147class ImageCodeEntry {
148public:
149
150 virtual inline
151 ~ImageCodeEntry(){};
152
153 virtual
154 bool empty() const = 0;
155};
156*/
157
158template <class T>
159typename ImageCodeMap<T>::lookup_t & ImageCodeMap<T>::createLookUp(const std::type_info & type, const ValueScaling & scaling) const { // todo N?
160
161 drain::Logger mout(__FILE__, __FUNCTION__);
162
163 //mout.warn("first entry: " , sprinter(*pal.begin()) );
164 //mout.warn("last entry: " , sprinter(*pal.rbegin()) );
165
166 lookUp.byteSize = drain::Type::call<drain::sizeGetter>(type);
167
168 // Todo: add support for signed short and signed char ?
169 if (type == typeid(unsigned short)){ // 1024 entries (not 65536)
170 if ((scaling.scale == 1.0) && (scaling.offset == 0.0)){
171 double first = this->begin()->first;
172 double last = this->rbegin()->first;
173 if ((first >= 0.0) && (last <= 255.0)){
174 lookUp.bitShift = 0;
175 mout.note("short int, but not using 16 bits, coping with 256 entries" );
176 }
177 else
178 lookUp.bitShift = 6;
179 }
180 else
181
182 lookUp.bitShift = 6; // note => 16 - 6 = 10 bits => 1024 entries
183 }
184 else if (type == typeid(unsigned char)){
185 lookUp.bitShift = 0;
186 }
187 else {
188 mout.note("not supported for type " , drain::Type::getTypeChar(type) );
189 lookUp.byteSize = 0;
190 lookUp.bitShift = 0;
191 lookUp.clear();
192 return lookUp;
193 }
194
195 const int n = (1 << (lookUp.byteSize*8 - lookUp.bitShift));
196 mout.debug("type=" , drain::Type::getTypeChar(type) , ", creating " , n , " lookup entries" );
197
198 typename cont_t::const_iterator itLower = this->begin();
199
200 lookUp.resize(n, itLower);
201
202 // Signed, because scaling physical values may cause underflow
203 int index, indexLower=0;
204
206 for (typename cont_t::const_iterator it=this->begin(); it!=this->end(); ++it){
207 //for (const auto & entry: *this){
208
209 index = static_cast<int>(scaling.inv(it->first));
210
211 if (index < 0){
212 mout.warn("underflow threshold " , it->first , " mapped to negative index " , index , " (before bitShift), skipping " );
213 continue;
214 }
215
216 index = (index >> lookUp.bitShift);
217
218 if (index >= n){
219 mout.warn("overflow: threshold ", it->first, " mapped to index (", index, ") > max (", (n-1), "), skipping " );
220 continue;
221 }
222
223 if (indexLower < index){
224 mout.debug("adding index range [", indexLower, '-', index, "[ -> (", itLower->first, ") => {", itLower->second, '}');
225 }
226 else {
227 mout.note("accuracy loss: skipped entry [" , index , "] => ", it->first );
228 }
229
231 for (int i=indexLower; i<index; ++i){
232 lookUp[i] = itLower;
233 }
234
235 indexLower = index;
236 itLower = it;
237
238 }
239
240 index = n;
241 if (indexLower < index){
242 mout.debug() << "padding [" << indexLower << '-' << index << "[ -> \t";
243 mout << '[' << itLower->first << "] // " << itLower->second << mout.endl;
244 }
245 for (int i=indexLower; i<index; ++i){
246 lookUp[i] = itLower;
247 }
248
249 return lookUp;
250 }
251
252
253} // drain::
254
255#endif
Definition ImageCodebook.h:52
ImageCodeMap()
Default constructor.
Definition ImageCodebook.h:69
lookup_t & createLookUp(const std::type_info &type, const ValueScaling &scaling) const
Creates a vector of 256 or 65535 entries for fast retrieval.
Definition ImageCodebook.h:159
drain::LookUp< typename cont_t::const_iterator > lookup_t
LOOK-UP table is an array of pointers to the actual Palette.
Definition ImageCodebook.h:61
ImageCodeMap(const cont_t &map)
Copy constructor //.
Definition ImageCodebook.h:79
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:312
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition Log.h:430
Logger & debug(const TT &... args)
Debug information.
Definition Log.h:666
Logger & note(const TT &... args)
For top-level information.
Definition Log.h:489
Look-up tables.
Definition LookUp.h:61
Linear scaling and physical range for image intensities.
Definition ValueScaling.h:64
double & scale
Multiplicative coefficient \i a in: y = ax + b.
Definition ValueScaling.h:68
double & offset
Additive coefficient \i b in: y = ax + b.
Definition ValueScaling.h:71
double inv(double y) const
Inverse scaling: given physically meaningful value y, returns the corresponding code value.
Definition ValueScaling.h:301
Definition DataSelector.cpp:1277