Skip to main content

Optimal Hard Threshold for Matrix Denoising


Off-the-shelf method for determining the optimal singular value truncation (hard threshold) for matrix denoising.

The method gives the optimal location both in the case of the known or unknown noise level.

Example


example example2

Reproduce the example


Create some data:

import numpy as np
import scipy as sci
import matplotlib.pyplot as plt
from optht import optht

t = np.arange(-2,2, 0.01)

Utrue = np.array(( [np.cos(17*t) * np.exp(-t**2) , np.sin(11*t)] )).T
Strue = np.array(( [2, 0], [0, .5] ))
Vtrue = np.array(( [np.sin(5*t) * np.exp(-t**2) , np.cos(13*t)] )).T

# construct image
X = Utrue.dot(Strue).dot(Vtrue.T)

# define the noise level and add
sigma = 0.5
X_noisy = X + sigma * np.random.standard_normal(X.shape)

Compute the singular value decomposition (SVD):

U, s, Vh = np.linalg.svd(X_noisy, full_matrices=False)

Determine optimal hard threshold and reconstruct image

k = optht(X_noisy, sv=s, sigma=None)
X_denoised = (U[:, range(k)] * s[range(k)]).dot(Vh[range(k),:])

Plot the results:

plt.subplot(131)
plt.imshow(X, cmap='gray', interpolation='bicubic')
plt.title('Original image')
plt.axis('off')

plt.subplot(132)
plt.imshow(X_noisy, cmap='gray', interpolation='bicubic')
plt.title('Noisy image, sigma=%s' % sigma)
plt.axis('off')

plt.subplot(133)
plt.imshow(X_denoised, cmap='gray', interpolation='bicubic')
rmseSVD = np.sqrt(np.sum( ( X - X_denoised )**2 ) / np.sum(X**2))
plt.title('Denoised image,  nrmse=%s ' % np.round(rmseSVD, 2))
plt.axis('off')
plt.show()

Plot the singular value spectrum:

plt.plot( (np.arange(1,s.shape[0]+1)), np.log(s), c='b', marker='o', linestyle='--')
plt.xlabel('k', fontsize=25)
plt.ylabel('Log-scaled singular values')
plt.tick_params(axis='x') 
plt.tick_params(axis='y') 
plt.title('Singular value spectrum')
plt.axvline(k, c='r', linewidth=2, linestyle='--')
plt.show()

Authors & Acknowledgments


  • Thanks to Steven Dahdah for refactoring the code into a Python package.
  • Thanks to Bill Tubbs for style edits and a few typo corrections.
  • Thanks to @nish-ant for adding fixes to make the code Python 3 compatible.

Notes


  • Code is adapted from Matan Gavish and David L. Donoho, see [1]. Corresponding MATLAB code can be found here

References


[1] Gavish, Matan, and David L. Donoho. "The optimal hard threshold for singular values is 4/sqrt(3)" IEEE Transactions on Information Theory 60.8 (2014): 5040-5053. http://arxiv.org/abs/1305.5870

Metadata

Release files for optht 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for optht 0.2.0
File Size Uploaded Provenance Actions
optht-0.2.0.tar.gz 3.9 kB Without provenance Details for optht-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for optht 0.2.0
File Interpreter ABI Platform Actions
optht-0.2.0-py3-none-any.whl Python 3 none any Details for optht-0.2.0-py3-none-any.whl

Total release size: 9.3 kB

Release files / optht-0.2.0.tar.gz

Download URL optht-0.2.0.tar.gz
Size 3.9 kB
Tags Source
SHA-256 checksum
How to use checksums
757c3606392cfef788b879ebc6bcaacedef6f1e44bbd6df49d3689a445cd948e
BLAKE2b-256 checksum
How to use checksums
0d4bf2e6e2ad35bd18a70113f9dfa7697024aaf38f75b6a47622c6ab28d262af
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.2 importlib_metadata/3.7.3 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.7.9

Release files / optht-0.2.0-py3-none-any.whl

Download URL optht-0.2.0-py3-none-any.whl
Size 5.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e09453b29aa51bc5ed9ef6b4071cdd0d4b355f97c6902398b9c183fb506c96f8
BLAKE2b-256 checksum
How to use checksums
0b24eacb4ba15cb39dbd87f9ed615c2acbb4f90101976584210e2fe43b10851c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.2 importlib_metadata/3.7.3 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.7.9

Security for optht 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page