KSquare Utilities
FlatFieldCorrection.cpp
Go to the documentation of this file.
1 /* FlatFieldCorrection.cpp --
2  * Copyright (C) 2011-2013 Kurt Kramer
3  * For conditions of distribution and use, see copyright notice in LarcosCounterUnManaged.txt
4  */
5 #include "FirstIncludes.h"
6 
7 #include <errno.h>
8 #include <istream>
9 #include <iostream>
10 #include <fstream>
11 #include <deque>
12 #include <vector>
13 #include "MemoryDebug.h"
14 using namespace std;
15 
16 
17 #include "KKBaseTypes.h"
18 #include "OSservices.h"
19 using namespace KKB;
20 
21 
23 using namespace KKLSC;
24 
25 
26 
28  kkint32 _lineWidth,
29  const uchar* _compensationTable
30  ):
31  compensationTable (_compensationTable),
32  enabled (true),
33  highPoint (NULL),
34  highPointLastSeen (NULL),
35  history (NULL),
36  lastHistoryIdxAdded (_numSampleLines - 1),
37  lineWidth (_lineWidth),
38  numSampleLines (_numSampleLines),
39  numSampleLinesAdded (0),
40  totalLine (NULL)
41 {
42  kkint32 x, y;
43 
44  highPoint = new uchar[lineWidth];
45  highPointLastSeen = new kkint32[lineWidth];
46  for (x = 0; x < lineWidth; x++)
47  {
48  highPoint [x] = 255;
49  highPointLastSeen[x] = 0;
50  }
51 
52  history = new uchar*[numSampleLines];
53  for (x = 0; x < numSampleLines; x++)
54  {
55  history[x] = new uchar[lineWidth];
56  for (y = 0; y < lineWidth; y++)
57  history[x][y] = 255;
58  }
59 
60  totalLine = new kkint32[lineWidth];
61 
62  lookUpTable = new uchar*[lineWidth];
63  for (x = 0; x < lineWidth; x++)
64  {
65  lookUpTable[x] = new uchar[256];
66  for (y = 0; y < 256; y++)
67  lookUpTable[x][y] = y;
68  }
69 
70  for (kkint32 col = 0; col < lineWidth; col++)
71  ReComputeLookUpForColumn (col);
72 }
73 
74 
75 
77 {
78  kkint32 x;
79 
80  delete highPoint; highPoint = NULL;
81  delete highPointLastSeen; highPointLastSeen = NULL;
82 
83  for (x = 0; x < numSampleLines; x++)
84  {
85  delete history[x];
86  history[x] = NULL;
87  }
88  delete history;
89  history = NULL;
90 
91  for (x = 0; x < lineWidth; x++)
92  {
93  delete lookUpTable[x];
94  lookUpTable[x] = NULL;
95  }
96 
97  delete lookUpTable; lookUpTable = NULL;
98  delete totalLine; totalLine = NULL;
99 }
100 
101 
102 void FlatFieldCorrection::CompensationTable (const uchar* _compensationTable)
103 {
104  compensationTable = _compensationTable;
105  for (kkint32 x = 0; x < lineWidth; ++x)
106  ReComputeLookUpForColumn (x);
107 }
108 
109 
110 
111 
112 void FlatFieldCorrection::AddSampleLine (const uchar* sampleLine)
113 {
114  lastHistoryIdxAdded++;
115  if (lastHistoryIdxAdded >= numSampleLines)
116  lastHistoryIdxAdded = 0;
117 
118  uchar* historyLine = history[lastHistoryIdxAdded];
119  for (kkint32 x = 0; x < lineWidth; ++x)
120  {
121  historyLine[x] = sampleLine[x];
122  if (sampleLine[x] < highPoint[x])
123  {
124  highPointLastSeen[x]++;
125  if (highPointLastSeen[x] > numSampleLines)
126  ReComputeLookUpForColumn (x);
127  }
128  else if ((sampleLine[x] - 5) > highPoint[x])
129  {
130  ReComputeLookUpForColumn (x);
131  highPointLastSeen[x] = 0;
132  }
133  else
134  {
135  highPointLastSeen[x] = 0;
136  }
137  }
138 
139  numSampleLinesAdded++;
140 } /* AddSampleLine */
141 
142 
143 
144 
145 void FlatFieldCorrection::ReComputeLookUpForColumn (kkint32 col)
146 {
147  if (enabled)
148  {
149  highPointLastSeen[col] = 1;
150 
151  kkint32 historyIdx = lastHistoryIdxAdded;
152 
153  kkint32 age = 1;
154  highPoint[col] = 0;
155 
156  kkint32 hp0 = 0, hp0Age =0;
157  kkint32 hp1 = 0, hp1Age =0;
158  kkint32 hp2 = 0, hp2Age =0;
159 
160  while (true)
161  {
162  uchar hv = history[historyIdx][col];
163  if (hv > hp0)
164  {
165  hp2 = hp1; hp2Age = hp1Age;
166  hp1 = hp0; hp1Age = hp0Age;
167  hp0 = hv; hp0Age = age;
168  }
169  else if (hv > hp1)
170  {
171  hp2 = hp1; hp2Age = hp1Age;
172  hp1 = hv; hp1Age = age;
173  }
174  else if (hv > hp2)
175  {
176  hp2 = hv; hp2Age = age;
177  }
178 
179  //if (hv > highPoint[col])
180  //{
181  // highPoint[col] = history[historyIdx][col];
182  // highPointLastSeen[col] = age;
183  //}
184  historyIdx--;
185  if (historyIdx < 0)
186  historyIdx = numSampleLines - 1;
187 
188  if (historyIdx == lastHistoryIdxAdded)
189  break;
190 
191  age++;
192  }
193 
194 
195  //highPoint[col] = (uchar)(((uint16)hp0 + (uint16)hp1 + (uint16)hp2) / (uint16)3);
196  //highPoint[col] = hp0;
197  //highPointLastSeen[col] = hp0Age;
198 
199  highPoint[col] = hp2;
200  highPointLastSeen[col] = hp2Age;
201 
202 
203  // We now know the high point value; lets scale the look-up-table for this column now.
204  kkint32 row = 0;
205  kkint32 hp = highPoint[col];
206 
207  if (hp < 28)
208  {
209  hp = 0;
210  kkint32 newPixelValue = 255;
211  if (compensationTable)
212  newPixelValue = compensationTable[newPixelValue];
213  newPixelValue = 255 - newPixelValue;
214  for (row = 0; row < 256; ++row)
215  lookUpTable[col][row] = newPixelValue;
216  }
217  else
218  {
219  kkint32 newPixelValue = 0;
220  //kkint32 hpThreshold = (kkint32)(0.5f + (float)hp * 15.0f / 16.0f);
221  //kkint32 hpThreshold = hp - 15;
222  //hp = Max (0, (hp - 10));
223  //hp = Max (0, (hp - 15));
224 
225  for (row = 0; row < 256; ++row)
226  {
227  if (row < hp)
228  newPixelValue = (kkint32)(0.5f + (255.0f * (float)row) / (float)hp);
229  else
230  newPixelValue = 255;
231 
232  if ((newPixelValue < 0) || (newPixelValue > 255))
233  {
234  cout << "Woaaaaa!!!!! it went beyond 255 or less that 0 [" << newPixelValue << "]." << endl;
235  }
236 
237  //lookUpTable[col][row] = (uchar)(255 - newPixelValue);
238  if (compensationTable)
239  newPixelValue = compensationTable[newPixelValue];
240 
241  newPixelValue = 255 - newPixelValue;
242 
243  lookUpTable[col][row] = (uchar)newPixelValue;
244  }
245  }
246  }
247  else
248  {
249  for (kkint32 row = 0; row < 256; ++row)
250  {
251  kkint32 newPixelValue = row;
252  if (compensationTable)
253  newPixelValue = compensationTable[newPixelValue];
254 
255  newPixelValue = 255 - newPixelValue;
256 
257  lookUpTable[col][row] = (uchar)newPixelValue;
258  }
259  }
260 } /* ReComputeLookUpForColumn */
261 
262 
263 
265 {
266  for (kkint32 col = 0; col < lineWidth; col++)
267  scanLine[col] = lookUpTable[col][scanLine[col]];
268 } /* ApplyFlatFieldCorrection */
269 
270 
271 
273  uchar* destScanLine
274  )
275 {
276  if (enabled)
277  {
278  for (kkint32 col = 0; col < lineWidth; col++)
279  destScanLine[col] = lookUpTable[col][srcScanLine[col]];
280  }
281  else
282  {
283  for (kkint32 col = 0; col < lineWidth; col++)
284  destScanLine[col] = srcScanLine[col];
285  }
286 } /* ApplyFlatFieldCorrection */
287 
288 
289 
291 {
292  vector<uchar>* results = new vector<uchar> ();
293  for (kkint32 x = 0; x < lineWidth; x++)
294  results->push_back (highPoint[x]);
295  return results;
296 } /* CameraHighPoints */
297 
298 
299 
301 {
302  n = Min (n, numSampleLines);
303 
304  vector<uchar>* highPoints = new vector<uchar>(lineWidth, 0);
305 
306  kkint32 row = lastHistoryIdxAdded;
307  for (kkint32 x = 0; x < n; ++x)
308  {
309  if (row < 0)
310  row = numSampleLines - 1;
311  uchar* sampleRow = history[row];
312 
313  for (kkint32 col = 0; col < lineWidth; ++col)
314  {
315  if (sampleRow[col] > (*highPoints)[col])
316  (*highPoints)[col] = sampleRow[col];
317  }
318  --row;
319  }
320  return highPoints;
321 } /* CameraHighPointsFromLastNSampleLines */
void ApplyFlatFieldCorrection(uchar *scanLine)
__int32 kkint32
Definition: KKBaseTypes.h:88
FlatFieldCorrection(kkint32 _numSampleLines, kkint32 _lineWidth, const uchar *_compensationTable)
void CompensationTable(const uchar *_compensationTable)
VectorUcharPtr CameraHighPoints() const
void AddSampleLine(const uchar *sampleLine)
Provide sample of one scan line as from the camera; where 0 = foreground and 255 = background...
KKTHread * KKTHreadPtr
unsigned char uchar
Unsigned character.
Definition: KKBaseTypes.h:77
Contains Classes that are specific to Cameras physical characteristics.
VectorUchar * VectorUcharPtr
Definition: KKBaseTypes.h:152
VectorUcharPtr CameraHighPointsFromLastNSampleLines(kkint32 n) const
Will return the high point for each pixel from the last &#39;n&#39; sample lines taken.
void ApplyFlatFieldCorrection(uchar *srcScanLine, uchar *destScanLine)