Skip to content

Commit d437757

Browse files
committed
Various fixes. Ready to be merged
1 parent 2200ba1 commit d437757

3 files changed

Lines changed: 108 additions & 79 deletions

File tree

chapter3/demo_smoothed_tv_inpainting.ipynb

Lines changed: 46 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@
2929
"- $f = m u_{\\mathrm{true}}$: observed incomplete image\n",
3030
"- $u$: reconstructed image\n",
3131
"\n",
32-
"We compute $u$ by minimising\n",
32+
"We compute $u$ by minimizing\n",
3333
"\n",
3434
"$$\n",
3535
"J(u)= {1 \\over 2}\\beta \\int_\\Omega m(u-f)^2\\,\\mathrm{d}x\n",
3636
"+ \\alpha \\int_\\Omega \\sqrt{||\\nabla u||^2 + \\varepsilon^2}~\\mathrm{d}x.\n",
3737
"$$\n",
3838
"\n",
3939
"The first term enforces agreement with the known image data, while\n",
40-
"the second term is a smoothed total variation regularisation term.\n",
40+
"the second term is a smoothed total variation regularization term.\n",
4141
"It promotes piecewise smooth solution and preserves edges\n",
4242
"$\\alpha$ and $\\beta$ control the balance between the data fidelity\n",
4343
"(fit to f) and smoothness.\n",
@@ -106,7 +106,7 @@
106106
"source": [
107107
"We use first order Lagrange elements for discretizing the image.\n",
108108
"In this space, the DOFs are the values of u at mesh vertices\n",
109-
"the solution is continous but has piecewise constant gradient"
109+
"the solution is continuous but has piecewise constant gradient"
110110
]
111111
},
112112
{
@@ -175,7 +175,7 @@
175175
"\n",
176176
"We construct a mask with random \"holes\" inside the square\n",
177177
"* small circular regions are removed and set to 0\n",
178-
"* everyhere else remains known (1)"
178+
"* everywhere else remains known (1)"
179179
]
180180
},
181181
{
@@ -209,12 +209,14 @@
209209
" # number of speckles\n",
210210
" num_speckles = 25\n",
211211
" # random centers\n",
212-
" generator = np.random.Generator(np.random.MT19937(0)) # random seed for reproducibility\n",
212+
" generator = np.random.Generator(\n",
213+
" np.random.MT19937(0)\n",
214+
" ) # random seed for reproducibility\n",
213215
"\n",
214216
" cx = generator.uniform(0.25, 0.75, num_speckles)\n",
215217
" cy = generator.uniform(0.25, 0.75, num_speckles)\n",
216218
" # random radii (small + varied)\n",
217-
" radii = generator.uniform(0.012, 0.035, num_speckles)\n",
219+
" radii = generator.uniform(0.012, 0.035, num_speckles)\n",
218220
" # create holes. mask =0 inside circles\n",
219221
" for i in range(num_speckles):\n",
220222
" r2 = (X - cx[i]) ** 2 + (Y - cy[i]) ** 2\n",
@@ -281,7 +283,7 @@
281283
"\n",
282284
"where # $\\varepsilon$ is the smoothing of the TV:\n",
283285
"* large $\\varepsilon$ smoother more like quadratic diffusion\n",
284-
"* small $\\varepsilon$ closer to true TV edge pereserving"
286+
"* small $\\varepsilon$ closer to true TV edge preserving"
285287
]
286288
},
287289
{
@@ -302,12 +304,12 @@
302304
"metadata": {},
303305
"source": [
304306
"Smoothed TV inpainting energy functional.\n",
305-
"We define the energy J(u) and use ufl.derivative to obtain\n",
306-
"the residual form F.\n",
307+
"We define the energy J(u) and use {py:func}`ufl.derivative` to obtain\n",
308+
"the residual form $F(u; v)=0 \\quad\\forall v\\in V$:\n",
307309
"\n",
308310
"$$\n",
309311
"J(u) = {1 \\over 2}\\beta\\int_\\Omega m(u-f)^2\\,dx\n",
310-
"+ \\alpha\\int_\\Omega \\sqrt{||\\nabla u||^2+\\varepsilon^2}\\,dx\n",
312+
"+ \\alpha\\int_\\Omega \\sqrt{||\\nabla u||^2+\\varepsilon^2}~\\mathrm{d}x\n",
311313
"$$\n",
312314
"\n",
313315
"Taking the first variation gives the weak form F(u; v).\n",
@@ -318,7 +320,7 @@
318320
"+ \\alpha\\int_\\Omega\n",
319321
"{\\nabla u\\cdot\\nabla v\n",
320322
"\\over\n",
321-
"\\sqrt{||\\nabla u||^2+\\varepsilon^2}}\\,dx\n",
323+
"\\sqrt{||\\nabla u||^2+\\varepsilon^2}}~\\mathrm{d}x\n",
322324
"= 0 \\quad \\forall v\\in V.\n",
323325
"$$"
324326
]
@@ -330,38 +332,22 @@
330332
"metadata": {},
331333
"outputs": [],
332334
"source": [
333-
"v = ufl.TestFunction(V)"
334-
]
335-
},
336-
{
337-
"cell_type": "code",
338-
"execution_count": null,
339-
"id": "0055665b",
340-
"metadata": {},
341-
"outputs": [],
342-
"source": [
335+
"v = ufl.TestFunction(V)\n",
336+
"\n",
343337
"J_energy = (\n",
344338
" 0.5 * beta * m * (u - f) ** 2 * ufl.dx\n",
345339
" + alpha * ufl.sqrt(ufl.inner(ufl.grad(u), ufl.grad(u)) + eps**2) * ufl.dx\n",
346-
")"
347-
]
348-
},
349-
{
350-
"cell_type": "code",
351-
"execution_count": null,
352-
"id": "3fbade6e",
353-
"metadata": {},
354-
"outputs": [],
355-
"source": [
340+
")\n",
341+
"\n",
356342
"F = ufl.derivative(J_energy, u, v)"
357343
]
358344
},
359345
{
360346
"cell_type": "markdown",
361-
"id": "77b7387d",
347+
"id": "163eb995",
362348
"metadata": {},
363349
"source": [
364-
"This formulation is based on total variation (TV) regulaization\n",
350+
"This formulation is based on total variation (TV) regularization\n",
365351
"for image denoising and inpainting\n",
366352
"{cite:t}`tv-RUDIN1992TV,tv-CHAN2001TV`."
367353
]
@@ -423,14 +409,14 @@
423409
"source": [
424410
"FEM Metrics\n",
425411
"Global number of degrees of freedom reports the size of the\n",
426-
"finite element discretisation H1 seminorm error measures the\n",
412+
"finite element discretization H1 seminorm error measures the\n",
427413
"gradient error\n",
428414
"\n",
429415
"$$\n",
430416
" \\vert\\vert\\nabla(u-u_{true})\\vert\\vert_{L_2 (\\Omega)}\n",
431417
"$$\n",
432418
"\n",
433-
"This is useful as TV regulization is gradient based.\n",
419+
"This is useful as TV regularization is gradient based.\n",
434420
"Smaller values mean the reconstruction recovers edge structure better"
435421
]
436422
},
@@ -622,7 +608,7 @@
622608
"$$\n",
623609
"\n",
624610
"A decrease in the objective show that the nonlinear optimization\n",
625-
"improved the damaged image undeer the smoothed TV model"
611+
"improved the damaged image under the smoothed TV model"
626612
]
627613
},
628614
{
@@ -654,15 +640,22 @@
654640
"J0 = 0.5 * float(beta) * J0_data + float(alpha) * J0_tv"
655641
]
656642
},
643+
{
644+
"cell_type": "markdown",
645+
"id": "f01dfcb3",
646+
"metadata": {},
647+
"source": [
648+
"Printing statements for validation and metrics\n",
649+
"If on main process"
650+
]
651+
},
657652
{
658653
"cell_type": "code",
659654
"execution_count": null,
660655
"id": "65e16ee1",
661656
"metadata": {},
662657
"outputs": [],
663658
"source": [
664-
"# Printing statments for validation and metrics\n",
665-
"# If on main process\n",
666659
"if msh.comm.rank == 0:\n",
667660
" print(\"---Smoothed TV inpainting results---\")\n",
668661
"\n",
@@ -699,7 +692,7 @@
699692
"We construct fields that allow us to visually asses the quality\n",
700693
"of the reconstruction\n",
701694
"$u-u_{true}$ is the global reconstruction error\n",
702-
"$(1-m)(u-u_{true})$ is the hole error, restriced to the missing regions"
695+
"$(1-m)(u-u_{true})$ is the hole error, restricted to the missing regions"
703696
]
704697
},
705698
{
@@ -727,7 +720,8 @@
727720
"To plot in matplotlib\n",
728721
"1. extract the coordinates of the DOFs\n",
729722
"2. extract the function-space dofmap connectivity (triangles)\n",
730-
"3. build a Triangulation object\n",
723+
"3. build a {py:class}`Triangulation<matplotlib.tri.Triangulation>` object\n",
724+
"\n",
731725
"This allows matplotlib to render the piecewise linear FEM solution"
732726
]
733727
},
@@ -739,18 +733,8 @@
739733
"outputs": [],
740734
"source": [
741735
"coords = V.tabulate_dof_coordinates()\n",
742-
"x, y = coords[:, 0], coords[:, 1]"
743-
]
744-
},
745-
{
746-
"cell_type": "code",
747-
"execution_count": null,
748-
"id": "8a5a2ec4",
749-
"metadata": {
750-
"lines_to_next_cell": 2
751-
},
752-
"outputs": [],
753-
"source": [
736+
"x, y = coords[:, 0], coords[:, 1]\n",
737+
"\n",
754738
"triangles = V.dofmap.list\n",
755739
"triang = mtri.Triangulation(x, y, triangles)"
756740
]
@@ -761,8 +745,8 @@
761745
"metadata": {},
762746
"source": [
763747
"Plotting\n",
764-
"We use tripcolor to plot scalar fields defined on a triangulated mesh\n",
765-
"shading= \"flat\" shows piecewise constant coloring per triangle\n",
748+
"We use {py:func}`matplotlib.pyplot.tripcolor` to plot scalar fields defined on a\n",
749+
"triangulated mesh shading= \"flat\" shows piecewise constant coloring per triangle\n",
766750
"which better reflects the discrete FEM representations"
767751
]
768752
},
@@ -796,7 +780,13 @@
796780
"lim = np.max(np.abs(u_minus_u_true.x.array))\n",
797781
"# $u-u_{true}$ is the global reconstruction error\n",
798782
"plot_field(\n",
799-
" axes[1, 1], u_minus_u_true.x.array, \"u - u_true\", fig, cmap=\"coolwarm\", vmin=-lim, vmax=lim\n",
783+
" axes[1, 1],\n",
784+
" u_minus_u_true.x.array,\n",
785+
" \"u - u_true\",\n",
786+
" fig,\n",
787+
" cmap=\"coolwarm\",\n",
788+
" vmin=-lim,\n",
789+
" vmax=lim,\n",
800790
")\n",
801791
"# Hole only errors\n",
802792
"lim = np.max(np.abs(hole_error_field.x.array))\n",
@@ -830,6 +820,7 @@
830820
],
831821
"metadata": {
832822
"jupytext": {
823+
"formats": "ipynb,py:light",
833824
"main_language": "python"
834825
}
835826
},

0 commit comments

Comments
 (0)