Total Variation Inpainting using Split Bregman
usolve_gs_inc.c
Go to the documentation of this file.
1 
41 
42 #ifndef DOXYGEN
43 #ifndef _VARYINGLAMBDA
44 /* Recursively include file twice to define both versions of UGaussSeidel */
45 #define _VARYINGLAMBDA 0
46 #include __FILE__ /* Define UGaussSeidelConstantLambda */
47 #define _VARYINGLAMBDA 1
48 #include __FILE__ /* Define UGaussSeidelVaryingLambda */
49 #else /* if _VARYINGLAMBDA is defined */
50 
51 #include "tvregopt.h"
52 
53 #if !_VARYINGLAMBDA
55 {
56 #define LAMBDA_INIT
57 #define LAMBDA_STEP
58 #define ALPHA(i) (ConstantAlpha)
59 #define DENOM_INTERIOR (DenomInterior)
60  const num ConstantAlpha = S->Alpha;
61  const num DenomInterior = ConstantAlpha + 4;
62 
63 #else
65 {
66 #define LAMBDA_INIT Lambda = VaryingLambda
67 #define LAMBDA_STEP Lambda += Width
68 #define ALPHA(i) (Lambda[i] / Gamma)
69 #define DENOM_INTERIOR (4 + ALPHA(x))
70  const num *VaryingLambda = S->Opt.VaryingLambda;
71  const num *Lambda;
72  const num Gamma = S->Opt.Gamma1;
73 #endif
74  num *u = S->u;
75 #ifndef TVREG_USEZ
76  const num *ztilde = S->f;
77 #else
78  const num *ztilde = (S->UseZ) ? S->ztilde : S->f;
79 #endif
80  const numvec2 *dtilde = S->dtilde;
81  const int Width = S->Width;
82  const int Height = S->Height;
83  const int NumChannels = S->NumChannels;
84  num unew, Norm = 0;
85  int x, y, k;
86 
87  for(k = 0; k < NumChannels; k++)
88  {
89  LAMBDA_INIT;
90 
91  /* Top-left corner */
92  unew = (ALPHA(0)*ztilde[0] - dtilde[0].x - dtilde[0].y
93  + u[1] + u[Width]) / (2 + ALPHA(0));
94  Norm += (unew - u[0]) * (unew - u[0]);
95  u[0] = unew;
96 
97  /* Top row, x = 1, ..., Width - 2 */
98  for(x = 1; x < Width - 1; x++)
99  {
100  unew = (ALPHA(x)*ztilde[x] - dtilde[x].x + dtilde[x - 1].x
101  - dtilde[x].y + u[x - 1] + u[x + 1] + u[x + Width])
102  / (3 + ALPHA(x));
103  Norm += (unew - u[x]) * (unew - u[x]);
104  u[x] = unew;
105  }
106 
107  /* Top-right corner */
108  unew = (ALPHA(x)*ztilde[x] - dtilde[x].y
109  + u[x - 1] + u[x + Width]) / (2 + ALPHA(x));
110  Norm += (unew - u[x]) * (unew - u[x]);
111  u[x] = unew;
112 
113  u += Width;
114  ztilde += Width;
115  dtilde += Width;
116  LAMBDA_STEP;
117 
118  /* Rows y = 1, ..., Height - 2 */
119  for(y = 1; y < Height - 1; y++,
120  u += Width, ztilde += Width, dtilde += Width)
121  {
122  /* Left edge */
123  unew = (ALPHA(0)*ztilde[0] - dtilde[0].x - dtilde[0].y
124  + dtilde[-Width].y + u[1] + u[-Width] + u[Width])
125  / (3 + ALPHA(0));
126  Norm += (unew - u[0]) * (unew - u[0]);
127  u[0] = unew;
128 
129  /* Interior */
130  for(x = 1; x < Width - 1; x++)
131  {
132  unew = (ALPHA(x)*ztilde[x] - dtilde[x].x + dtilde[x - 1].x
133  - dtilde[x].y + dtilde[x - Width].y
134  + u[x - 1] + u[x + 1] + u[x - Width] + u[x + Width])
135  / DENOM_INTERIOR;
136 
137  Norm += (unew - u[x]) * (unew - u[x]);
138  u[x] = unew;
139  }
140 
141  /* Right edge */
142  unew = (ALPHA(x)*ztilde[x] - dtilde[x].y + dtilde[x - Width].y
143  + u[x - 1] + u[x - Width] + u[x + Width]) / (3 + ALPHA(x));
144  Norm += (unew - u[x]) * (unew - u[x]);
145  u[x] = unew;
146  LAMBDA_STEP;
147  }
148 
149  /* Bottom-left corner */
150  unew = (ALPHA(0)*ztilde[0] - dtilde[0].x
151  + u[1] + u[-Width]) / (2 + ALPHA(0));
152  Norm += (unew - u[0]) * (unew - u[0]);
153  u[0] = unew;
154 
155  /* Bottom row, x = 1, ..., Width - 2 */
156  for(x = 1; x < Width - 1; x++)
157  {
158  unew = (ALPHA(x)*ztilde[x] - dtilde[x].x + dtilde[x - 1].x
159  + u[x - 1] + u[x + 1] + u[x - Width]) / (3 + ALPHA(x));
160  Norm += (unew - u[x]) * (unew - u[x]);
161  u[x] = unew;
162  }
163 
164  /* Bottom-right corner */
165  unew = (ALPHA(x)*ztilde[x] + u[x - 1] + u[x - Width])
166  / (2 + ALPHA(x));
167  Norm += (unew - u[x]) * (unew - u[x]);
168  u[x] = unew;
169 
170  u += Width;
171  ztilde += Width;
172  dtilde += Width;
173  }
174 
175  return (num)sqrt(Norm) / S->fNorm;
176 #undef DENOM_INTERIOR
177 #undef LAMBDA_INIT
178 #undef LAMBDA_STEP
179 #undef ALPHA
180 #undef _VARYINGLAMBDA
181 }
182 
183 #endif /* _VARYINGLAMBDA */
184 #endif /* DOXYGEN */