pottslab 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. pottslab-1.0.0/.github/workflows/build_wheels.yml +126 -0
  2. pottslab-1.0.0/.gitignore +29 -0
  3. pottslab-1.0.0/Auxiliary/Operators/convop.m +30 -0
  4. pottslab-1.0.0/Auxiliary/Operators/linop.m +66 -0
  5. pottslab-1.0.0/Auxiliary/Operators/radonop.m +25 -0
  6. pottslab-1.0.0/Auxiliary/convkernel.m +46 -0
  7. pottslab-1.0.0/Auxiliary/countJumps.m +6 -0
  8. pottslab-1.0.0/Auxiliary/energyL2Potts.m +66 -0
  9. pottslab-1.0.0/Auxiliary/intmatrix.m +13 -0
  10. pottslab-1.0.0/Auxiliary/medianw.m +21 -0
  11. pottslab-1.0.0/Auxiliary/plimage2double.m +7 -0
  12. pottslab-1.0.0/Auxiliary/plpsnr.m +10 -0
  13. pottslab-1.0.0/Auxiliary/psnr.m +13 -0
  14. pottslab-1.0.0/Auxiliary/randidx.m +11 -0
  15. pottslab-1.0.0/Auxiliary/randl.m +11 -0
  16. pottslab-1.0.0/Auxiliary/samplesToWeights.m +20 -0
  17. pottslab-1.0.0/Auxiliary/segToLabel.m +26 -0
  18. pottslab-1.0.0/Auxiliary/setPLJavaPath.m +40 -0
  19. pottslab-1.0.0/Auxiliary/showPotts.m +30 -0
  20. pottslab-1.0.0/Auxiliary/showSparse.m +34 -0
  21. pottslab-1.0.0/Auxiliary/showdbl.m +46 -0
  22. pottslab-1.0.0/Auxiliary/softThreshold.m +8 -0
  23. pottslab-1.0.0/Auxiliary/spconvmatrix.m +21 -0
  24. pottslab-1.0.0/Auxiliary/spdiffmatrix.m +12 -0
  25. pottslab-1.0.0/CHANGELOG.md +57 -0
  26. pottslab-1.0.0/CITATION.cff +113 -0
  27. pottslab-1.0.0/Cargo.lock +323 -0
  28. pottslab-1.0.0/Cargo.toml +25 -0
  29. pottslab-1.0.0/Data/church.jpg +0 -0
  30. pottslab-1.0.0/Data/colors.png +0 -0
  31. pottslab-1.0.0/Data/desert.jpg +0 -0
  32. pottslab-1.0.0/Data/imageSources.txt +11 -0
  33. pottslab-1.0.0/Data/loadPcwConst.m +151 -0
  34. pottslab-1.0.0/Data/loadSparse.m +102 -0
  35. pottslab-1.0.0/Data/lookmickey.jpg +0 -0
  36. pottslab-1.0.0/Demos/1D/demoL1iPotts_DecImp.m +33 -0
  37. pottslab-1.0.0/Demos/1D/demoL1iPotts_DecLap.m +32 -0
  38. pottslab-1.0.0/Demos/1D/demoL1iSpars_DecImp.m +30 -0
  39. pottslab-1.0.0/Demos/1D/demoL1iSpars_DecLap.m +27 -0
  40. pottslab-1.0.0/Demos/1D/demoL2iPotts_Deconv.m +26 -0
  41. pottslab-1.0.0/Demos/1D/demoL2iPotts_Fourier.m +29 -0
  42. pottslab-1.0.0/Demos/1D/demoL2iPotts_Linop.m +34 -0
  43. pottslab-1.0.0/Demos/1D/demoL2iSpars_Deconv.m +27 -0
  44. pottslab-1.0.0/Demos/1D/demoPotts_GaussianNoise.m +19 -0
  45. pottslab-1.0.0/Demos/1D/demoPotts_ImpulsiveNoise.m +21 -0
  46. pottslab-1.0.0/Demos/1D/demoPotts_LaplacianNoise.m +19 -0
  47. pottslab-1.0.0/Demos/2D/demoPotts2DColorDenoising.m +25 -0
  48. pottslab-1.0.0/Demos/2D/demoPotts2DColorInpainting.m +33 -0
  49. pottslab-1.0.0/Demos/2D/demoPotts2DColorMissing.m +32 -0
  50. pottslab-1.0.0/Demos/2D/demoPotts2DColorSegmentation.m +29 -0
  51. pottslab-1.0.0/Demos/2D/demoPotts2DRadon.m +39 -0
  52. pottslab-1.0.0/Demos/2D/results/plFigPottsRec7Angles.fig +0 -0
  53. pottslab-1.0.0/Demos/pottsLabDemo.m +8 -0
  54. pottslab-1.0.0/Docs/deconv/noisy.png +0 -0
  55. pottslab-1.0.0/Docs/deconv/uPottsRho.png +0 -0
  56. pottslab-1.0.0/Docs/potts1d.png +0 -0
  57. pottslab-1.0.0/Docs/radon/phantom.png +0 -0
  58. pottslab-1.0.0/Docs/radon/recFBP.png +0 -0
  59. pottslab-1.0.0/Docs/radon/recFBPRamLak.png +0 -0
  60. pottslab-1.0.0/Docs/radon/recPotts.png +0 -0
  61. pottslab-1.0.0/Docs/texture.png +0 -0
  62. pottslab-1.0.0/Docs/titleImage.png +0 -0
  63. pottslab-1.0.0/Java/bin/pottslab/Benchmark$Thunk.class +0 -0
  64. pottslab-1.0.0/Java/bin/pottslab/Benchmark.class +0 -0
  65. pottslab-1.0.0/Java/bin/pottslab/IndexedLinkedHistogram$HistNode.class +0 -0
  66. pottslab-1.0.0/Java/bin/pottslab/IndexedLinkedHistogram.class +0 -0
  67. pottslab-1.0.0/Java/bin/pottslab/IndexedLinkedHistogramUnweighted$HistNode.class +0 -0
  68. pottslab-1.0.0/Java/bin/pottslab/IndexedLinkedHistogramUnweighted.class +0 -0
  69. pottslab-1.0.0/Java/bin/pottslab/JavaTools.class +0 -0
  70. pottslab-1.0.0/Java/bin/pottslab/L2Potts.class +0 -0
  71. pottslab-1.0.0/Java/bin/pottslab/PLImage$1.class +0 -0
  72. pottslab-1.0.0/Java/bin/pottslab/PLImage.class +0 -0
  73. pottslab-1.0.0/Java/bin/pottslab/PLProcessor.class +0 -0
  74. pottslab-1.0.0/Java/bin/pottslab/PLVector.class +0 -0
  75. pottslab-1.0.0/Java/bin/pottslab/RunMe.class +0 -0
  76. pottslab-1.0.0/Java/src/META-INF/MANIFEST.MF +3 -0
  77. pottslab-1.0.0/Java/src/pottslab/Benchmark.java +184 -0
  78. pottslab-1.0.0/Java/src/pottslab/IndexedLinkedHistogram.java +349 -0
  79. pottslab-1.0.0/Java/src/pottslab/IndexedLinkedHistogramUnweighted.java +240 -0
  80. pottslab-1.0.0/Java/src/pottslab/JavaTools.java +309 -0
  81. pottslab-1.0.0/Java/src/pottslab/L2Potts.java +136 -0
  82. pottslab-1.0.0/Java/src/pottslab/PLImage.java +170 -0
  83. pottslab-1.0.0/Java/src/pottslab/PLProcessor.java +306 -0
  84. pottslab-1.0.0/Java/src/pottslab/PLVector.java +258 -0
  85. pottslab-1.0.0/Java/src/pottslab/RunMe.java +38 -0
  86. pottslab-1.0.0/LICENSE +21 -0
  87. pottslab-1.0.0/License.txt +21 -0
  88. pottslab-1.0.0/PKG-INFO +327 -0
  89. pottslab-1.0.0/PORTED_BY.md +60 -0
  90. pottslab-1.0.0/Plugins/PottsSegmentationJ_.jar +0 -0
  91. pottslab-1.0.0/Potts/PottsCore/findBestPartition.m +116 -0
  92. pottslab-1.0.0/Potts/PottsCore/iPottsADMM.m +147 -0
  93. pottslab-1.0.0/Potts/PottsCore/reconstructionFromPartition.m +56 -0
  94. pottslab-1.0.0/Potts/minL1Potts.m +80 -0
  95. pottslab-1.0.0/Potts/minL1iPotts.m +22 -0
  96. pottslab-1.0.0/Potts/minL2Potts.m +55 -0
  97. pottslab-1.0.0/Potts/minL2iPotts.m +22 -0
  98. pottslab-1.0.0/Potts2D/Core/iPotts2DADMM.m +203 -0
  99. pottslab-1.0.0/Potts2D/minL2Potts2DADMM.m +68 -0
  100. pottslab-1.0.0/Potts2D/minL2iPotts2DADMM.m +5 -0
  101. pottslab-1.0.0/README.md +151 -0
  102. pottslab-1.0.0/README_PYTHON.md +296 -0
  103. pottslab-1.0.0/Sparsity/SparsityCore/iSparsADMM.m +138 -0
  104. pottslab-1.0.0/Sparsity/SparsityCore/iSparsByPottsADMM.m +54 -0
  105. pottslab-1.0.0/Sparsity/SparsityCore/minSpars.m +14 -0
  106. pottslab-1.0.0/Sparsity/minL1Spars.m +11 -0
  107. pottslab-1.0.0/Sparsity/minL1iSpars.m +25 -0
  108. pottslab-1.0.0/Sparsity/minL2Spars.m +11 -0
  109. pottslab-1.0.0/Sparsity/minL2iSpars.m +36 -0
  110. pottslab-1.0.0/Tikhonov/minL1Tikhonov.m +117 -0
  111. pottslab-1.0.0/Tikhonov/minL2Tikhonov.m +98 -0
  112. pottslab-1.0.0/Tikhonov/minL2TikhonovFBP.m +57 -0
  113. pottslab-1.0.0/benchmark.py +316 -0
  114. pottslab-1.0.0/installPottslab.m +39 -0
  115. pottslab-1.0.0/pottslab/__init__.py +105 -0
  116. pottslab-1.0.0/pottslab/_core.pyi +63 -0
  117. pottslab-1.0.0/pottslab/_core_py.py +349 -0
  118. pottslab-1.0.0/pottslab/inverse.py +210 -0
  119. pottslab-1.0.0/pottslab/potts1d.py +159 -0
  120. pottslab-1.0.0/pottslab/potts2d.py +133 -0
  121. pottslab-1.0.0/pottslab/sparsity.py +103 -0
  122. pottslab-1.0.0/pottslab/tikhonov.py +131 -0
  123. pottslab-1.0.0/pottslab/utils.py +171 -0
  124. pottslab-1.0.0/pottslab-standalone.jar +0 -0
  125. pottslab-1.0.0/pyproject.toml +46 -0
  126. pottslab-1.0.0/src/admm.rs +246 -0
  127. pottslab-1.0.0/src/l1potts.rs +414 -0
  128. pottslab-1.0.0/src/l2potts.rs +127 -0
  129. pottslab-1.0.0/src/lib.rs +131 -0
  130. pottslab-1.0.0/src/processor.rs +167 -0
  131. pottslab-1.0.0/tests/conftest.py +47 -0
  132. pottslab-1.0.0/tests/test_brute_force.py +201 -0
  133. pottslab-1.0.0/tests/test_edge_cases.py +421 -0
  134. pottslab-1.0.0/tests/test_hardening.py +590 -0
  135. pottslab-1.0.0/tests/test_integration.py +204 -0
  136. pottslab-1.0.0/tests/test_inverse.py +80 -0
  137. pottslab-1.0.0/tests/test_l1_median_bug.py +282 -0
  138. pottslab-1.0.0/tests/test_l1_potts_1d.py +92 -0
  139. pottslab-1.0.0/tests/test_l2_potts_1d.py +195 -0
  140. pottslab-1.0.0/tests/test_matlab_parity.py +257 -0
  141. pottslab-1.0.0/tests/test_numerical_precision.py +228 -0
  142. pottslab-1.0.0/tests/test_potts_2d.py +105 -0
  143. pottslab-1.0.0/tests/test_properties.py +267 -0
  144. pottslab-1.0.0/tests/test_sparsity.py +84 -0
  145. pottslab-1.0.0/tests/test_tikhonov.py +61 -0
  146. pottslab-1.0.0/tests/test_utils.py +129 -0
@@ -0,0 +1,126 @@
1
+ name: Build and publish wheels
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*" # run on version tags, e.g. v1.0.1
7
+ workflow_dispatch: # allow manual runs from the Actions UI
8
+
9
+ jobs:
10
+ # ── Build platform wheels ──────────────────────────────────────────────────
11
+ build_wheels:
12
+ name: Build ${{ matrix.target }} wheel
13
+ runs-on: ${{ matrix.os }}
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ include:
18
+ # Linux — x86_64 (manylinux, covers most servers and desktops)
19
+ - os: ubuntu-latest
20
+ target: x86_64
21
+ manylinux: auto
22
+
23
+ # Linux — aarch64 (Raspberry Pi, AWS Graviton, Apple M-series via
24
+ # emulation; QEMU is set up automatically by maturin-action)
25
+ - os: ubuntu-latest
26
+ target: aarch64
27
+ manylinux: auto
28
+
29
+ # macOS — Apple Silicon
30
+ # Intel macOS (macos-13) was dropped: GitHub-hosted Intel runners are
31
+ # being retired and queue depth made the job time out at the 24h
32
+ # maximum. Intel-Mac users can install from the sdist.
33
+ - os: macos-14
34
+ target: aarch64
35
+
36
+ # Windows — x86_64
37
+ - os: windows-latest
38
+ target: x86_64
39
+
40
+ steps:
41
+ - uses: actions/checkout@v4
42
+
43
+ # Native Windows/macOS runners only have one Python on PATH by default,
44
+ # so maturin's --interpreter 3.9..3.13 lookup fails. Pre-installing all
45
+ # five versions via setup-python adds them to PATH. The manylinux
46
+ # container build skips this step (the host setup doesn't reach inside
47
+ # the container, which already ships every CPython we need).
48
+ - name: Set up Python (native runners only)
49
+ if: matrix.manylinux != 'auto'
50
+ uses: actions/setup-python@v5
51
+ with:
52
+ python-version: |
53
+ 3.9
54
+ 3.10
55
+ 3.11
56
+ 3.12
57
+ 3.13
58
+
59
+ - name: Build wheels
60
+ uses: PyO3/maturin-action@v1
61
+ with:
62
+ target: ${{ matrix.target }}
63
+ manylinux: ${{ matrix.manylinux || '' }}
64
+ # Build for every supported CPython interpreter.
65
+ # PyPy is excluded because PyO3 support requires extra setup.
66
+ args: >-
67
+ --release
68
+ --out dist
69
+ --interpreter 3.9 3.10 3.11 3.12 3.13
70
+
71
+ - name: Upload wheel artifacts
72
+ uses: actions/upload-artifact@v4
73
+ with:
74
+ name: wheels-${{ matrix.target }}-${{ matrix.os }}
75
+ path: dist/*.whl
76
+
77
+ # ── Build source distribution ──────────────────────────────────────────────
78
+ build_sdist:
79
+ name: Build source distribution
80
+ runs-on: ubuntu-latest
81
+ steps:
82
+ - uses: actions/checkout@v4
83
+
84
+ - name: Build sdist
85
+ uses: PyO3/maturin-action@v1
86
+ with:
87
+ command: sdist
88
+ args: --out dist
89
+
90
+ - name: Upload sdist artifact
91
+ uses: actions/upload-artifact@v4
92
+ with:
93
+ name: sdist
94
+ path: dist/*.tar.gz
95
+
96
+ # ── Publish to PyPI ────────────────────────────────────────────────────────
97
+ publish:
98
+ name: Publish to PyPI
99
+ runs-on: ubuntu-latest
100
+ needs: [build_wheels, build_sdist]
101
+ # Only publish on version-tag pushes, not on workflow_dispatch
102
+ if: startsWith(github.ref, 'refs/tags/v')
103
+ # Requires an environment named "pypi" configured in the repo settings
104
+ # with PyPI as a trusted publisher (no API token needed).
105
+ environment:
106
+ name: pypi
107
+ url: https://pypi.org/project/pottslab/
108
+ permissions:
109
+ id-token: write # required for OIDC trusted publishing
110
+
111
+ steps:
112
+ - name: Download all wheel and sdist artifacts
113
+ uses: actions/download-artifact@v4
114
+ with:
115
+ merge-multiple: true
116
+ path: dist
117
+
118
+ - name: Publish to PyPI
119
+ uses: pypa/gh-action-pypi-publish@release/v1
120
+ # Uses PyPI OIDC trusted publishing — no API token required.
121
+ # Set up at: https://pypi.org/manage/account/publishing/
122
+ # Project name: pottslab
123
+ # Owner: mstorath
124
+ # Repository: Pottslab
125
+ # Workflow: build_wheels.yml
126
+ # Environment: pypi
@@ -0,0 +1,29 @@
1
+ # Rust build artifacts
2
+ target/
3
+ Cargo.lock.bak
4
+
5
+ # Compiled Python extension (platform-specific; built by CI)
6
+ pottslab/_core*.so
7
+ pottslab/_core*.pyd
8
+
9
+ # Python cache
10
+ __pycache__/
11
+ *.pyc
12
+ *.pyo
13
+ .pytest_cache/
14
+
15
+ # macOS
16
+ .DS_Store
17
+
18
+ # Distribution / packaging
19
+ dist/
20
+ *.egg-info/
21
+ .eggs/
22
+
23
+ # Editors / IDEs
24
+ .vscode/
25
+ .idea/
26
+ *.swp
27
+
28
+ # Jupyter
29
+ .ipynb_checkpoints/
@@ -0,0 +1,30 @@
1
+ classdef convop < double
2
+ %convop A class for circular convolution by FFT
3
+
4
+ % written by M. Storath
5
+ % $Date: 2014-05-07 11:42:11 +0200 (Mi, 07. Mai 2014) $ $Revision: 89 $
6
+
7
+
8
+ methods
9
+ % constructor
10
+ function obj = convop(fourier)
11
+ obj = obj@double(fourier);
12
+ end
13
+
14
+ % ctranspose (')
15
+ function C = ctranspose(A)
16
+ C = convop(conj(A));
17
+ end
18
+
19
+ % mtimes (*)
20
+ function C = mtimes( A, B )
21
+ if isa(B, 'convop')
22
+ C = convop( A .* B );
23
+ else
24
+ C = ifftn( A .* fftn(B) );
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+
@@ -0,0 +1,66 @@
1
+ classdef linop
2
+ %linop A class for linear operators
3
+
4
+ % written by M. Storath
5
+ % $Date: 2015-10-15 15:07:43 +0200 (Do, 15. Okt 2015) $ $Revision: 132 $
6
+
7
+
8
+ properties
9
+ % function handle for evaluation A * x
10
+ eval;
11
+ % function handle for evaluation A' * x
12
+ ctrans;
13
+ % A'A
14
+ normalOp;
15
+ % true if A'A positive definite
16
+ posdef;
17
+ % true if A'A positive definite
18
+ lseSolver;
19
+ end
20
+
21
+ methods
22
+ % constructor
23
+ function A = linop(eval, ctrans, varargin)
24
+ % if it is a matrix
25
+ if ~isa(eval, 'function_handle')
26
+ A.eval = @(x) eval * x;
27
+ A.ctrans = @(x) eval' * x;
28
+ M = eval' * eval;
29
+ A.normalOp = @(x) M * x;
30
+ else
31
+ A.eval = eval;
32
+ A.ctrans = ctrans;
33
+ A.normalOp = @(x) A.ctrans(A.eval(x));
34
+ end
35
+ ip = inputParser;
36
+ addParamValue(ip, 'posdef', false);
37
+ addParamValue(ip, 'lseSolver', []);
38
+ parse(ip, varargin{:});
39
+ par = ip.Results;
40
+ A.posdef = par.posdef;
41
+ A.lseSolver = par.lseSolver;
42
+ end
43
+
44
+ % ctranspose (')
45
+ function C = ctranspose(A)
46
+ C = linop(A.ctrans, A.eval);
47
+ end
48
+
49
+ % mtimes (*)
50
+ function C = mtimes( A, B )
51
+ if isa(B, 'linop')
52
+ C = linop( @(x) A.eval(B.eval(x)), @(x) B.ctrans(A.ctrans(x)));
53
+ else
54
+ C = A.eval(B);
55
+ end
56
+ end
57
+
58
+ % size
59
+ function s = size(A)
60
+ %warning('Size is deprecated for class linop');
61
+ s = [1 1];
62
+ end
63
+
64
+ end
65
+ end
66
+
@@ -0,0 +1,25 @@
1
+ classdef radonop < linop
2
+ %radonop A class for Radon transform
3
+
4
+ % written by M. Storath
5
+ % $Date: 2014-09-02 14:56:23 +0200 (Di, 02. Sep 2014) $ $Revision: 105 $
6
+
7
+ properties
8
+ % solution method for prox
9
+ useFBP;
10
+ end
11
+
12
+ methods
13
+ % constructor
14
+ function A = radonop(theta, imgSize)
15
+
16
+ eval = @(x) radon(x, theta);
17
+ ctrans = @(x) iradon(x, theta, 'linear', 'None', 1, imgSize);
18
+
19
+ A = A@linop(eval, ctrans);
20
+ A.posdef = true;
21
+ A.useFBP = false;
22
+ end
23
+ end
24
+ end
25
+
@@ -0,0 +1,46 @@
1
+ function h = convkernel( type, n, scale )
2
+ %CONVKERNEL Creates a convolution kernel
3
+
4
+ % written by M. Storath
5
+ % $Date: 2012/10/29 01:19:08 $ $Revision: 0.1 $
6
+
7
+ if not(exist('scale', 'var'))
8
+ scale = 1;
9
+ end
10
+
11
+ % set coordinates
12
+ d = n/2;
13
+ x = linspace(-d, d, n)/scale;
14
+
15
+ switch type
16
+ case 'box'
17
+ h = ones(n, 1);
18
+
19
+ case 'hat'
20
+ h(x >= 0) = 1-x(x >= 0);
21
+ h(x < 0) = 1 + x(x < 0);
22
+ h(abs(x) > 1) = 0;
23
+
24
+ case 'gaussian'
25
+ h = exp(-0.5 * x.^2);
26
+
27
+ case 'doubleexp'
28
+ h = exp(-0.5 * abs(x));
29
+
30
+ case 'mollifier'
31
+ h = exp(-1./(1 - abs(x).^2));
32
+ h(abs(x) > 1) = 0;
33
+
34
+ case 'ramp'
35
+ h(x >= 0) = 1-x(x >= 0);
36
+ h(abs(x) > 1) = 0;
37
+
38
+ otherwise
39
+ error('This option does not exist.')
40
+ end
41
+
42
+ % normalize
43
+ h = h(:)./sum(h);
44
+
45
+ end
46
+
@@ -0,0 +1,6 @@
1
+ function j = countJumps( f )
2
+ %COUNTJUMPS Counts the jumps of a vector f
3
+ j = sum( diff(f) ~= 0);
4
+
5
+ end
6
+
@@ -0,0 +1,66 @@
1
+ function [energy, jumpPenalty, dataError] = energyL2Potts( u, f, gamma, A, isotropic )
2
+ %energyL2Potts Computes the energy of the L2 Potts functional
3
+
4
+ if exist('A', 'var') && not(isempty(A))
5
+ Au = A * u;
6
+ dataError = sum((Au(:) - f(:)).^2);
7
+ else
8
+ dataError = sum((u(:) - f(:)).^2);
9
+ end
10
+
11
+
12
+ if isvector(u)
13
+ % vectors
14
+ jumpPenalty = sum(diff(u(:)) ~= 0);
15
+ else
16
+ % matrices
17
+ nJumpComp = 0; % jumps in compass directions
18
+ nJumpDiag = 0; % jumps in diagonal directions
19
+
20
+ % count jumps
21
+ for i = 1:size(u, 1)
22
+ for j = 1:size(u, 2)-1
23
+ if ~all((u(i,j,:) == u(i,j+1,:)))
24
+ nJumpComp = nJumpComp + 1;
25
+ end
26
+ end
27
+ end
28
+ for i = 1:size(u, 1)-1
29
+ for j = 1:size(u, 2)
30
+ if ~all((u(i,j,:) == u(i+1,j,:)))
31
+ nJumpComp = nJumpComp + 1;
32
+ end
33
+ end
34
+ end
35
+ for i = 1:size(u, 1)-1
36
+ for j = 1:size(u, 2)-1
37
+ if ~all((u(i,j,:) == u(i+1,j+1,:)))
38
+ nJumpDiag = nJumpDiag + 1;
39
+ end
40
+ end
41
+ end
42
+ for i = 1:size(u, 1)-1
43
+ for j = 2:size(u, 2)
44
+ if ~all((u(i,j,:) == u(i+1,j-1,:)))
45
+ nJumpDiag = nJumpDiag + 1;
46
+ end
47
+ end
48
+ end
49
+
50
+ % set weights (isotropic by default)
51
+ if ~exist('isotropic', 'var') || isotropic
52
+ omega1 = sqrt(2) - 1;
53
+ omega2 = 1 - sqrt(2)/2;
54
+ else
55
+ omega1 = 1;
56
+ omega2 = 0;
57
+ end
58
+
59
+ % compute energy
60
+ jumpPenalty = (omega1 * nJumpComp + omega2* nJumpDiag);
61
+
62
+ end
63
+
64
+ energy = gamma * jumpPenalty + dataError;
65
+
66
+ end
@@ -0,0 +1,13 @@
1
+ function A = intmatrix( n )
2
+ %INTMATRIX Creates a matrix that acts as integration
3
+ % (cumulative sum) on the input vector
4
+ %
5
+ % Au = cumsum(u)
6
+
7
+ % written by M. Storath
8
+ % $Date: 2012/10/29 01:19:08 $ $Revision: 0.1 $
9
+
10
+ A = tril(ones(n));
11
+
12
+ end
13
+
@@ -0,0 +1,21 @@
1
+ function mu = medianw( data, weight )
2
+ % medianw Computes a weighted median of the data
3
+
4
+ % written by M. Storath
5
+ % $Date: 2012/10/29 01:19:08 $ $Revision: 0.1 $
6
+
7
+ if numel(data) == 1
8
+ mu = data;
9
+ else
10
+ [dataSorted, idx] = sort(data);
11
+ weightSorted = weight(idx);
12
+ weightSum = sum(weight);
13
+ cumWeight = cumsum(weightSorted)/weightSum;
14
+ % find first median index
15
+ idx = find(cumWeight < 0.5, 1, 'last' ) + 1;
16
+ if isempty(idx)
17
+ idx = 1;
18
+ end
19
+ mu = dataSorted(idx);
20
+ end
21
+
@@ -0,0 +1,7 @@
1
+ function img = plimage2double( plimg )
2
+ %PLIMAGE2DOUBLE Summary of this function goes here
3
+ % Detailed explanation goes here
4
+ img = reshape(plimg.toDouble(), [plimg.mRow, plimg.mCol, plimg.mLen]);
5
+
6
+ end
7
+
@@ -0,0 +1,10 @@
1
+ function r = plpsnr( groundTruth, signal )
2
+ %plPSNR Computes the peak signal to noise ratio
3
+
4
+ % written by M. Storath
5
+ % $Date: 2014-05-07 14:23:10 +0200 (Mi, 07. Mai 2014) $ $Revision: 90 $
6
+
7
+ mse = mean(abs(signal(:) - groundTruth(:)).^2);
8
+ r = 10 * log10(max(groundTruth(:))^2 / mse);
9
+
10
+ end
@@ -0,0 +1,13 @@
1
+ function r = psnr( groundTruth, signal )
2
+ %PSNR Computes the peak signal to noise ratio
3
+
4
+ % written by M. Storath
5
+ % $Date: 2012/10/29 01:19:08 $ $Revision: 0.1 $
6
+
7
+ warning('The function psnr conflicts with the new function psnr from the image processing toolbox from Matlab v2014a. Use plpsnr instead.')
8
+
9
+ mse = mean(abs(signal(:) - groundTruth(:)).^2);
10
+ r = 10 * log10(max(groundTruth(:))^2 / mse);
11
+
12
+ end
13
+
@@ -0,0 +1,11 @@
1
+ function idx = randidx( siz, fraction )
2
+ %randidx Selects randomly a fraction of indices for a matrix of size siz
3
+
4
+ % written by M. Storath
5
+ % $Date: 2012/10/29 01:19:08 $ $Revision: 0.1 $
6
+
7
+ n = prod(siz);
8
+ idx = randperm(n) ;
9
+ idx = idx(1:round(fraction * n));
10
+ end
11
+
@@ -0,0 +1,11 @@
1
+ function y = randl( varargin )
2
+ %randl Random normal Laplacian noise, mean = 0, variance sigma^2 = 1
3
+ % pdf: $\frac{1}{\sqrt{2}} e^{- \sqrt{2} |x|}$
4
+
5
+ % written by M. Storath
6
+ % $Date: 2012/10/29 01:19:08 $ $Revision: 0.1 $
7
+
8
+ x = rand( varargin{:} ) - 0.5;
9
+ y = -sign(x) .* log(1 - 2 * abs(x)) / sqrt(2);
10
+ end
11
+
@@ -0,0 +1,20 @@
1
+ function weights = samplesToWeights( samples )
2
+ %samplesToWeights Computes weights from a set of sample points
3
+
4
+ % written by M. Storath
5
+ % $Date: 2012/10/29 01:19:08 $ $Revision: 0.1 $
6
+
7
+ %init
8
+ weights = zeros(size(samples));
9
+
10
+ % first and last weight
11
+ weights(1) = samples(2) - samples(1);
12
+ weights(end) = samples(end) - samples(end-1);
13
+
14
+ % central weights
15
+ subs = 2:numel(samples)-1;
16
+ weights(subs) = 0.5 * ( abs(samples(subs) - samples(subs-1)) ...
17
+ + abs(samples(subs) - samples(subs+1)) );
18
+
19
+ end
20
+
@@ -0,0 +1,26 @@
1
+ function labelImg = segToLabel(u, conn)
2
+ %SEGTOLABEL Converts the output image of a segmentation function (e.g. minL2Potts2DADMM) to a
3
+ %label image with integer labels (each connected component gets a unique integer)
4
+ % u: image to label (typically the output of minL2Potts2DADMM))
5
+ % conn: connectivity as in bwconncomp (default: 8)
6
+
7
+ if ~exist('conn', 'var')
8
+ conn = 8;
9
+ end
10
+
11
+ [m,n,c] = size(u);
12
+ vals = unique(reshape(u, m*n, c), 'rows');
13
+ labelImg = zeros(m, n);
14
+ labelCounter = 0;
15
+ for i=1:size(vals,1)
16
+ bw_mult = (vals(i,:) == reshape(u, m*n, c));
17
+ bw = bw_mult(:,1);
18
+ CC = bwconncomp(reshape(double(bw), m, n), conn);
19
+ for j = 1:CC.NumObjects
20
+ labelImg(CC.PixelIdxList{j}) = labelCounter;
21
+ labelCounter = labelCounter + 1;
22
+ end
23
+ end
24
+
25
+ end
26
+
@@ -0,0 +1,40 @@
1
+ function setPLJavaPath(static)
2
+
3
+ % the path
4
+ jpath = fullfile( fileparts(which(mfilename)), '..', 'Java', 'bin');
5
+
6
+ % dynamic path
7
+ javaaddpath(jpath);
8
+
9
+ % static path
10
+ if exist('static', 'var') && static
11
+ % static path (is faster, requires restart to take effect)
12
+ upath = userpath;
13
+ jpathfile = fullfile(upath, 'javaclasspath.txt');
14
+ disp(['Appending java class path to ' jpathfile]);
15
+ pathExists = false;
16
+ % check if path exists
17
+ currentPath = javaclasspath('-static');
18
+
19
+ for i = 1:numel(currentPath)
20
+ pathExists = strcmp(currentPath{i}, jpath) || pathExists;
21
+ end
22
+ % append path to classpath
23
+ if ~pathExists
24
+ try
25
+ fid = fopen(jpathfile, 'at');
26
+ fprintf(fid, '\n');
27
+ % windows path need double backslash
28
+ jpath = strrep(jpath,'\','\\');
29
+ fprintf(fid, jpath);
30
+ fclose(fid);
31
+ catch
32
+ warning('Failed to add java path to static class path. Using dynamic classpath instead. This requires you to call setPLJavaPath.m each time you use Pottslab.')
33
+ end
34
+ end
35
+ end
36
+
37
+
38
+
39
+ end
40
+
@@ -0,0 +1,30 @@
1
+ function showPotts(data, rec, groundTruth, method)
2
+ %showPotts Display result of Potts reconstructions
3
+
4
+ subplot(1,2,1)
5
+ plot(data, '.', 'MarkerSize', 10)
6
+ title('Data')
7
+
8
+ % reconstruction
9
+ subplot(1,2,2)
10
+ plot(rec, '.', 'MarkerSize', 10)
11
+
12
+ % legend
13
+ if ~exist('method', 'var')
14
+ leg = {'Reconstruction'};
15
+ else
16
+ leg = {method};
17
+ end
18
+
19
+ % add groundTruth
20
+ if exist('groundTruth', 'var')
21
+ hold on
22
+ plot(groundTruth, '--r')
23
+ hold off
24
+ leg = [leg, {'Ground truth'}];
25
+ title(['PSNR: ' num2str(plpsnr(groundTruth, rec)), ', #Jumps: ', num2str(countJumps(rec))] );
26
+ end
27
+
28
+ legend(leg);
29
+
30
+ end
@@ -0,0 +1,34 @@
1
+ function showSparse(data, rec, groundTruth, method)
2
+ %showSparse Display result of sparse reconstructions
3
+
4
+ % written by M. Storath
5
+ % $Date: 2012/10/29 01:19:08 $ $Revision: 0.1 $
6
+
7
+ % data
8
+ subplot(1,2,1)
9
+ plot(data)
10
+ title('Data')
11
+
12
+ % reconstruction
13
+ subplot(1,2,2)
14
+ plot(rec, '.', 'MarkerSize', 10)
15
+
16
+ % legend
17
+ if ~exist('method', 'var')
18
+ leg = {'Reconstruction'};
19
+ else
20
+ leg = {method};
21
+ end
22
+
23
+ % add groundTruth
24
+ if exist('groundTruth', 'var')
25
+ hold on
26
+ stem(groundTruth, 'r')
27
+ hold off
28
+ leg = [leg, {'Ground truth'}];
29
+ title(['PSNR: ' num2str(plpsnr(groundTruth, rec))] );
30
+ end
31
+
32
+ legend(leg);
33
+
34
+ end