31 float DiagonalAverage(
const float *Image,
int Width,
int Height,
int x,
int y);
32 float AxialAverage(
const float *Image,
int Width,
int Height,
int x,
int y);
61 int Width,
int Height,
int RedX,
int RedY,
int UseZhangCodeEst)
66 const float DivEpsilon = 0.1f/(255*255);
68 static float InterpCoeff[5] = {-0.25f, 0.5f, 0.5f, 0.5f, -0.25f};
70 static float SmoothCoeff[9] = {0.03125f, 0.0703125f, 0.1171875f,
71 0.1796875f, 0.203125f, 0.1796875f, 0.1171875f, 0.0703125f, 0.03125f};
77 const int NumPixels = Width*Height;
78 const int Green = 1 - ((RedX + RedY) & 1);
79 float *OutputRed = Output;
80 float *OutputGreen = Output + NumPixels;
81 float *OutputBlue = Output + 2*NumPixels;
82 float *FilteredH = NULL, *FilteredV = NULL;
83 float *DiffH = NULL, *DiffV = NULL, *DiffGR, *DiffGB;
84 float mom1, h, H, mh, ph, Rh, v, V, mv, pv, Rv, Temp;
85 int x, y, i, m, m0, m1, Success = 0;
89 if(!(FilteredH = (
float *)
Malloc(
sizeof(
float)*NumPixels))
90 || !(FilteredV = (
float *)
Malloc(
sizeof(
float)*NumPixels))
91 || !(DiffGR = DiffH = (
float *)
Malloc(
sizeof(
float)*NumPixels))
92 || !(DiffGB = DiffV = (
float *)
Malloc(
sizeof(
float)*NumPixels)))
96 for(y = 0; y < Height; y++)
97 Conv1D(FilteredH + Width*y, 1,
98 Input + Width*y, 1, InterpFilter, Boundary, Width);
100 for(x = 0; x < Width; x++)
101 Conv1D(FilteredV + x, Width,
102 Input + x, Width, InterpFilter, Boundary, Height);
105 for(y = 0, i = 0; y < Height; y++)
106 for(x = 0; x < Width; x++, i++)
108 if(((x + y) & 1) == Green)
110 DiffH[i] = Input[i] - FilteredH[i];
111 DiffV[i] = Input[i] - FilteredV[i];
115 DiffH[i] = FilteredH[i] - Input[i];
116 DiffV[i] = FilteredV[i] - Input[i];
121 for(y = 0; y < Height; y++)
122 Conv1D(FilteredH + Width*y, 1, DiffH + Width*y, 1,
123 SmoothFilter, Boundary, Width);
125 for(x = 0; x < Width; x++)
126 Conv1D(FilteredV + x, Width, DiffV + x, Width,
127 SmoothFilter, Boundary, Height);
130 for(y = 0, i = 0; y < Height; y++)
131 for(x = 0; x < Width; x++, i++)
133 if(((x + y) & 1) != Green)
138 m0 = (x >= M) ? -M : -x;
139 m1 = (x < Width - M) ? M : (Width - x - 1);
150 for(m = m0, mom1 = ph = Rh = 0; m <= m1; m++)
152 Temp = FilteredH[i + m];
155 Temp -= DiffH[i + m];
166 ph = ph/(2*M) - mom1*mom1/(2*M*(2*M + 1));
167 Rh = Rh/(2*M + 1) + DivEpsilon;
168 h = mh + (ph/(ph + Rh))*(DiffH[i] - mh);
169 H = ph - (ph/(ph + Rh))*ph + DivEpsilon;
172 m0 = (y >= M) ? -M : -y;
173 m1 = (y < Height - M) ? M : (Height - y - 1);
184 for(m = m0, mom1 = pv = Rv = 0; m <= m1; m++)
186 Temp = FilteredV[i + Width*m];
189 Temp -= DiffV[i + Width*m];
200 pv = pv/(2*M) - mom1*mom1/(2*M*(2*M + 1));
201 Rv = Rv/(2*M + 1) + DivEpsilon;
202 v = mv + (pv/(pv + Rv))*(DiffV[i] - mv);
203 V = pv - (pv/(pv + Rv))*pv + DivEpsilon;
207 OutputGreen[i] = Input[i] + (V*h + H*v) / (H + V);
210 OutputGreen[i] = Input[i];
216 for(y = 0, i = 0; y < Height; y++)
217 for(x = 0; x < Width; x++, i++)
218 if(((x + y) & 1) != Green)
219 (((y & 1) == RedY) ? DiffGR : DiffGB)[i]
220 = OutputGreen[i] - Input[i];
223 for(y = 0, i = 0; y < Height; y++)
224 for(x = 0; x < Width; x++, i++)
225 if(((x + y) & 1) != Green)
234 for(y = 0, i = 0; y < Height; y++)
235 for(x = 0; x < Width; x++, i++)
236 if(((x + y) & 1) == Green)
243 for(y = 0, i = 0; y < Height; y++)
244 for(x = 0; x < Width; x++, i++)
246 OutputRed[i] = OutputGreen[i] - DiffGR[i];
247 OutputBlue[i] = OutputGreen[i] - DiffGB[i];
275 Image += x + Width*y;
280 return Image[1 + Width];
281 else if(x < Width - 1)
282 return (Image[-1 + Width] + Image[1 + Width]) / 2;
284 return Image[-1 + Width];
286 else if(y < Height - 1)
289 return (Image[1 - Width] + Image[1 + Width]) / 2;
290 else if(x < Width - 1)
291 return (Image[-1 - Width] + Image[1 - Width]
292 + Image[-1 + Width] + Image[1 + Width]) / 4;
294 return (Image[-1 - Width] + Image[-1 + Width]) / 2;
299 return Image[1 - Width];
300 else if(x < Width - 1)
301 return (Image[-1 - Width] + Image[1 - Width]) / 2;
303 return Image[-1 - Width];
318 float AxialAverage(
const float *Image,
int Width,
int Height,
int x,
int y)
320 Image += x + Width*y;
325 return (Image[1] + Image[Width]) / 2;
326 else if(x < Width - 1)
327 return (Image[-1] + Image[1] + 2*Image[Width]) / 4;
329 return (Image[-1] + Image[Width]) / 2;
332 else if(y < Height - 1)
335 return (2*Image[1] + Image[-Width] + Image[Width]) / 4;
336 else if(x < Width - 1)
337 return (Image[-1] + Image[1] + Image[-Width] + Image[Width]) / 4;
339 return (2*Image[-1] + Image[-Width] + Image[Width]) / 4;
344 return (Image[1] + Image[-Width])/2;
345 else if(x < Width - 1)
346 return (Image[-1] + Image[1] + 2*Image[-Width]) / 4;
348 return (Image[-1] + Image[-Width]) / 2;