-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
zysOAOA
committed
Jan 7, 2019
0 parents
commit fd294a7
Showing
3 changed files
with
123 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#!/usr/bin/env python | ||
# -*- coding:utf-8 -*- | ||
# Power by Zongsheng Yue 2019-01-07 14:36:55 | ||
|
||
|
||
import numpy as np | ||
from cv2 import imread | ||
from utils import im2patch, im2double | ||
import time | ||
|
||
def noise_estimate(im, pch_size=8): | ||
''' | ||
Implement of noise level estimation of the following paper: | ||
Chen G , Zhu F , Heng P A . An Efficient Statistical Method for Image Noise Level Estimation[C]// 2015 IEEE International Conference | ||
on Computer Vision (ICCV). IEEE Computer Society, 2015. | ||
Input: | ||
im: the noise image, H x W x 3 or H x W numpy tensor, range [0,1] | ||
pch_size: patch_size | ||
Output: | ||
noise_level: the estimated noise level | ||
''' | ||
|
||
if im.ndim == 3: | ||
im = im.transpose((2, 0, 1)) | ||
else: | ||
im = np.expand_dims(im, axis=0) | ||
|
||
# image to patch | ||
pch = im2patch(im, pch_size, 3) # C x pch_size x pch_size x num_pch tensor | ||
num_pch = pch.shape[3] | ||
pch = pch.reshape((-1, num_pch)) # d x num_pch matrix | ||
d = pch.shape[0] | ||
|
||
mu = pch.mean(axis=1, keepdims=True) # d x 1 | ||
X = pch - mu | ||
sigma_X = np.matmul(X, X.transpose()) / num_pch | ||
sig_value, _ = np.linalg.eigh(sigma_X) | ||
sig_value.sort() | ||
|
||
for ii in range(-1, -d-1, -1): | ||
tau = np.mean(sig_value[:ii]) | ||
if np.sum(sig_value[:ii]>tau) == np.sum(sig_value[:ii] < tau): | ||
return np.sqrt(tau) | ||
|
||
|
||
if __name__ == '__main__': | ||
im = imread('./lena.png') | ||
im = im2double(im) | ||
|
||
noise_level = [5, 15, 20, 30, 40] | ||
|
||
for level in noise_level: | ||
sigma = level / 255 | ||
|
||
im_noise = im + np.random.randn(*im.shape) * sigma | ||
|
||
start = time.time() | ||
est_level = noise_estimate(im_noise, 8) | ||
end = time.time() | ||
time_elapsed = end -start | ||
|
||
str_p = "Time: {0:.4f}, Ture Level: {1:6.4f}, Estimated Level: {2:6.4f}" | ||
print(str_p.format(time_elapsed, level, est_level*255)) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
#!/usr/bin/env python | ||
# -*- coding:utf-8 -*- | ||
# Power by Zongsheng Yue 2019-01-07 15:13:19 | ||
|
||
import numpy as np | ||
import sys | ||
from math import floor | ||
|
||
def im2patch(im, pch_size, stride=1): | ||
''' | ||
Transform image to patches. | ||
Input: | ||
im: 3 x H x W or 1 X H x W image, numpy format | ||
pch_size: (int, int) tuple or integer | ||
stride: (int, int) tuple or integer | ||
''' | ||
if isinstance(pch_size, tuple): | ||
pch_H, pch_W = pch_size | ||
elif isinstance(pch_size, int): | ||
pch_H = pch_W = pch_size | ||
else: | ||
sys.exit('The input of pch_size must be a integer or a int tuple!') | ||
|
||
if isinstance(stride, tuple): | ||
stride_H, stride_W = stride | ||
elif isinstance(stride, int): | ||
stride_H = stride_W = stride | ||
else: | ||
sys.exit('The input of stride must be a integer or a int tuple!') | ||
|
||
|
||
C, H, W = im.shape | ||
num_H = len(range(0, H-pch_H+1, stride_H)) | ||
num_W = len(range(0, W-pch_W+1, stride_W)) | ||
num_pch = num_H * num_W | ||
pch = np.zeros((C, pch_H*pch_W, num_pch), dtype=im.dtype) | ||
kk = 0 | ||
for ii in range(pch_H): | ||
for jj in range(pch_W): | ||
temp = im[:, ii:H-pch_H+ii+1:stride_H, jj:W-pch_W+jj+1:stride_W] | ||
pch[:, kk, :] = temp.reshape((C, num_pch)) | ||
kk += 1 | ||
|
||
return pch.reshape((C, pch_H, pch_W, num_pch)) | ||
|
||
def im2double(im): | ||
''' | ||
Input: | ||
im: numpy uint format image, RGB or Gray, | ||
''' | ||
|
||
im = im.astype(np.float) | ||
min_val = np.min(im.ravel()) | ||
max_val = np.max(im.ravel()) | ||
|
||
out = (im - min_val) / (max_val - min_val) | ||
|
||
return out |