├── LICENSE ├── README.md ├── __init__.py ├── data └── kodak │ ├── kodim01.png │ ├── kodim02.png │ ├── kodim03.png │ ├── kodim04.png │ ├── kodim05.png │ ├── kodim06.png │ ├── kodim07.png │ ├── kodim08.png │ ├── kodim09.png │ ├── kodim10.png │ ├── kodim11.png │ ├── kodim12.png │ ├── kodim13.png │ ├── kodim14.png │ ├── kodim15.png │ ├── kodim16.png │ ├── kodim17.png │ ├── kodim18.png │ ├── kodim19.png │ ├── kodim20.png │ ├── kodim21.png │ ├── kodim22.png │ ├── kodim23.png │ └── kodim24.png ├── data_v3.py ├── data_v3.pyc ├── drdd_dn_sigma0_50.py ├── evaluate.py ├── generate_noisy_images.py ├── matlab ├── .DS_Store └── Chen_ICCV2015_code │ ├── .DS_Store │ ├── Demo.m │ ├── NoiseEstimation.m │ ├── generate_all.m │ ├── generate_sigmas.m │ ├── image2cols.m │ ├── imdata │ ├── 104010.jpg │ ├── 14085.jpg │ ├── 15011.jpg │ ├── 317043.jpg │ └── 43033.jpg │ ├── rawdata │ ├── .DS_Store │ ├── im1_bright.png │ ├── im1_dark.png │ ├── im1_no_gamma.png │ └── im1_normal.png │ └── rawdemo.m ├── model_noise_estimation_w64d16_v2_sigma0_30.py ├── models ├── .DS_Store ├── dn_sigma0_50 │ ├── deep_isp.pickle │ └── loss.txt └── ne_w64d16_v2_sigma0_30 │ ├── checkpoint │ ├── loss.txt │ ├── tf_denoiser.ckpt.data-00000-of-00001 │ ├── tf_denoiser.ckpt.index │ └── tf_denoiser.ckpt.meta ├── network_dn.py ├── res ├── .DS_Store ├── chen+dn │ ├── .DS_Store │ └── kodak_sigma15 │ │ ├── kodim01.png │ │ ├── kodim02.png │ │ ├── kodim03.png │ │ ├── kodim04.png │ │ ├── kodim05.png │ │ ├── kodim06.png │ │ ├── kodim07.png │ │ ├── kodim08.png │ │ ├── kodim09.png │ │ ├── kodim10.png │ │ ├── kodim11.png │ │ ├── kodim12.png │ │ ├── kodim13.png │ │ ├── kodim14.png │ │ ├── kodim15.png │ │ ├── kodim16.png │ │ ├── kodim17.png │ │ ├── kodim18.png │ │ ├── kodim19.png │ │ ├── kodim20.png │ │ ├── kodim21.png │ │ ├── kodim22.png │ │ ├── kodim23.png │ │ └── kodim24.png └── drne+dn │ ├── .DS_Store │ └── kodak_sigma15 │ ├── kodim01.png │ ├── kodim02.png │ ├── kodim03.png │ ├── kodim04.png │ ├── kodim05.png │ ├── kodim06.png │ ├── kodim07.png │ ├── kodim08.png │ ├── kodim09.png │ ├── kodim10.png │ ├── kodim11.png │ ├── kodim12.png │ ├── kodim13.png │ ├── kodim14.png │ ├── kodim15.png │ ├── kodim16.png │ ├── kodim17.png │ ├── kodim18.png │ ├── kodim19.png │ ├── kodim20.png │ ├── kodim21.png │ ├── kodim22.png │ ├── kodim23.png │ └── kodim24.png ├── test_chen_and_dn.py └── test_drne_and_dn.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Hanlin_Tan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pixel-wise Estimation of Signal Dependent Image Noise using Deep Residual Learning 2 | 3 | 4 | Hanlin Tan, Huaxin Xiao, Shiming Lai, Yu Liu and Maojun Zhang 5 | 6 | National University of Defense Technology, China 7 | 8 | 9 | ## Applying DRNE to Deep Denoising Model 10 | 11 | The code is written in Python 2.7 using Tensorflow 1.4. To evaluate Chen's method, you also need to install Matlab. 12 | 13 | We only include `Kodak` dataset images in `data` folder to reduce the attachment size. You can download `McM` and `BSD500` from the Internet if you want to see results on those two datasets. 14 | 15 | 16 | 17 | The following steps reproduce the results in Section IV-E. 18 | 19 | + run `generate_noisy_images.py` to genereate noisy dataset from groundtruth images. 20 | 21 | + run `matlab/chenxxx/generate_all.m` to genereate noise estimation results, which will be stored in `data/chen`. 22 | 23 | + run `test_drne_and_dn.py` to generate denoised images with the proposed DRNE + a CNN denoiser. 24 | 25 | + run `test_chen_and_dn.py` to enerate denoised images with the Chen's method + the CNN denoiser. 26 | 27 | + run `evaluate.py` to get the quantitative evaluation results. 28 | 29 | Since we uploaded pre-computed results, you can directly run the last step to get the quantitative evaluation results. 30 | 31 | Note we use random numbers in noisy image generation. The absolute performance is expected to show a small difference but the performance gain should stay the same. 32 | 33 | ## Train Your Own Model 34 | + Download [Waterloo](https://ece.uwaterloo.ca/~k29ma/exploration) dataset, [Kodak](http://www.cs.albany.edu/~xypan/research/snr/Kodak.html) dataset and [McM](https://www4.comp.polyu.edu.hk/~cslzhang/CDM_Dataset.htm) dataset and put the images in the data folder such as: 35 | 36 | ``` 37 | ├── data 38 | │ ├── kodak 39 | │ ├── mcm 40 | │ └── pristine_images 41 | ``` 42 | 43 | + Run `data_v3.py` to generate cache files of images in `data` folder. If you need to use your own dataset, update function `create_pristine`, accordingly. 44 | + Update configuration part of `model_noise_estimation_w64d16_v2_sigma0_30.py` by setting `bTrain = True`. For example, 45 | 46 | ```python 47 | if __name__ == '__main__': 48 | ## configuration 49 | bTrain = True 50 | modelPath = 'ne_w64d16_v2_sigma0_30' 51 | width = 64 52 | depth = 16 - 4 53 | device = '0' 54 | minNoiseLevel = 0.0 / 255.0 55 | maxNoiseLevel = 30.0 / 255.0 56 | #### end configuration 57 | 58 | if bTrain: 59 | train('models/%s' % modelPath, 'data/pristine_rgb2gray.h5', 60 | 'data/kodak_rgb2gray.h5', width, depth, minNoiseLevel, maxNoiseLevel, device=device, x_shape=[128, 128, 3], 61 | y_shape=[128, 128, 3]) 62 | else: 63 | parser = argparse.ArgumentParser() 64 | parser.add_argument('--noise', type=float, default=0.0, 65 | help='standard deviation of additive Gaussian noise, w.r.t to a [0,1] intensity scale.') 66 | args = parser.parse_args() 67 | 68 | noise = 5 69 | 70 | test('models/%s' % modelPath, width, depth=depth, device=device, noise=noise) 71 | ``` 72 | + Start training by 73 | ``` 74 | python model_noise_estimation_w64d16_v2_sigma0_30.py 75 | ``` 76 | 77 | # Reference 78 | If you use the code in your work, please cite our paper: 79 | 80 | ``` 81 | @article{tan2019pixelwise, 82 | title={Pixelwise Estimation of Signal-Dependent Image Noise Using Deep Residual Learning}, 83 | author={Tan, Hanlin and Xiao, Huaxin and Lai, Shiming and Liu, Yu and Zhang, Maojun}, 84 | journal={Computational intelligence and neuroscience}, 85 | volume={2019}, 86 | year={2019}, 87 | publisher={Hindawi} 88 | } 89 | ``` 90 | 91 | 92 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/__init__.py -------------------------------------------------------------------------------- /data/kodak/kodim01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim01.png -------------------------------------------------------------------------------- /data/kodak/kodim02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim02.png -------------------------------------------------------------------------------- /data/kodak/kodim03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim03.png -------------------------------------------------------------------------------- /data/kodak/kodim04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim04.png -------------------------------------------------------------------------------- /data/kodak/kodim05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim05.png -------------------------------------------------------------------------------- /data/kodak/kodim06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim06.png -------------------------------------------------------------------------------- /data/kodak/kodim07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim07.png -------------------------------------------------------------------------------- /data/kodak/kodim08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim08.png -------------------------------------------------------------------------------- /data/kodak/kodim09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim09.png -------------------------------------------------------------------------------- /data/kodak/kodim10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim10.png -------------------------------------------------------------------------------- /data/kodak/kodim11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim11.png -------------------------------------------------------------------------------- /data/kodak/kodim12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim12.png -------------------------------------------------------------------------------- /data/kodak/kodim13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim13.png -------------------------------------------------------------------------------- /data/kodak/kodim14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim14.png -------------------------------------------------------------------------------- /data/kodak/kodim15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim15.png -------------------------------------------------------------------------------- /data/kodak/kodim16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim16.png -------------------------------------------------------------------------------- /data/kodak/kodim17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim17.png -------------------------------------------------------------------------------- /data/kodak/kodim18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim18.png -------------------------------------------------------------------------------- /data/kodak/kodim19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim19.png -------------------------------------------------------------------------------- /data/kodak/kodim20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim20.png -------------------------------------------------------------------------------- /data/kodak/kodim21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim21.png -------------------------------------------------------------------------------- /data/kodak/kodim22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim22.png -------------------------------------------------------------------------------- /data/kodak/kodim23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim23.png -------------------------------------------------------------------------------- /data/kodak/kodim24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data/kodak/kodim24.png -------------------------------------------------------------------------------- /data_v3.py: -------------------------------------------------------------------------------- 1 | # coding=utf8 2 | # Author: TomHeaven, 2017.08.19 3 | from __future__ import print_function 4 | import numpy as np 5 | import h5py 6 | import os 7 | import re 8 | from numpy.lib import stride_tricks 9 | import cv2 10 | import tifffile as tiff 11 | 12 | 13 | DEBUG = False 14 | 15 | class DatabaseCreator: 16 | #### input or output type 17 | IM_RGB = 0 # 三通道RGB图 18 | IM_GRAY = 1 # 二维灰度图 19 | IM_BAYER = 2 # 二维Bayer格式 20 | IM_BAYER3 = 4 # 三通道Bayer格式 21 | IM_RAW = 5 # 自定义raw格式 22 | IM_TIFF_16 = 6 # uint16 tiff图像 23 | 24 | # 输出图像的格式 25 | FMT_RGB = 0 26 | FMT_LAB = 1 27 | FMT_YUV = 2 28 | 29 | #### parameters 30 | inputFolder = 'data' 31 | outputPath = 'train.h5' 32 | ext = 'jpg|tif|tiff|png' 33 | inImageType = IM_RGB 34 | outImageType = IM_GRAY 35 | patchSize = 128 36 | stride = 128 37 | unit_norm = 4 38 | 39 | inBayerType = 'gbrg' 40 | outBayerType = 'gbrg' 41 | 42 | inDataType = np.uint8 43 | 44 | 45 | def __init__(self, inputFolder = '.', outputPath = 'data.h5', ext = 'jpg|JPG|tif|tiff|png|bmp', inImageType = IM_RGB, \ 46 | outImageType = IM_GRAY, inBayerType = 'gbrg', outBayerType = 'gbrg', inDataType = np.uint8, patchSize = 128, stride = 128, 47 | unit_norm=4, save_format= FMT_RGB): 48 | """ 49 | initialize all parameters 50 | :param inputFolder: 51 | :param outputPath: 52 | :param ext: 53 | :param inImageType: 54 | :param outImageType: 55 | :param inBayerType: 56 | :param outBayerType: 57 | :param patchSize: 58 | :param stride: 59 | """ 60 | self.inputFolder = inputFolder 61 | self.outputPath = outputPath 62 | self.ext = ext 63 | self.inImageType = inImageType 64 | self.outImageType = outImageType 65 | self.inBayerType = inBayerType 66 | self.outBayerType = outBayerType 67 | self.inDataType = inDataType 68 | self.patchSize = patchSize 69 | self.stride = stride 70 | self.uint_norm = unit_norm 71 | self.save_format = save_format 72 | 73 | def read_raw(self, path, height=3024, width=4032): 74 | """ 75 | read self-defined raw format, 16 bit uint 76 | :param height: 77 | :param width: 78 | :return: the raw data 79 | """ 80 | file = open(path, "rb") 81 | rawdata = file.read() 82 | image = np.zeros([height, width], dtype=np.uint16) 83 | cout = 0 84 | for i in range(height): 85 | for j in range(width): 86 | image[i, j] = ord(rawdata[cout + 1]) * 256 + ord(rawdata[cout]) 87 | cout += 2 88 | # print 'cout : ', cout 89 | file.close() 90 | return image 91 | 92 | def write_raw(self, path, image): 93 | """ 94 | write self-defined raw format, 16 bit uint 95 | :param image: 96 | :return: None 97 | """ 98 | file = open(path, "wb") 99 | file.write(image) 100 | file.close() 101 | 102 | def swap_red_blue(self, image): 103 | """ 104 | swap blue and red channel of image 105 | :param image: image data 106 | :return: channel-swapped image 107 | """ 108 | R = image[:, :, 0].copy() 109 | B = image[:, :, 2].copy() 110 | image[:, :, 0] = B 111 | image[:, :, 2] = R 112 | return image 113 | 114 | def cutup(self, data, blck, strd): 115 | """ 116 | convert three channel image data to strided patches 117 | :param data: image data in 3d 118 | :param blck: patch size in 3d 119 | :param strd: stride in 3d 120 | :return: the patches 121 | """ 122 | sh = np.array(data.shape) 123 | blck = np.asanyarray(blck) 124 | strd = np.asanyarray(strd) 125 | nbl = (sh - blck) // strd + 1 126 | strides = np.r_[data.strides * strd, data.strides] 127 | dims = np.r_[nbl, blck] 128 | data6 = stride_tricks.as_strided(data, strides=strides, shape=dims) 129 | return data6.reshape(-1, *blck) 130 | #return data6.reshape(-1, blck[0], blck[1], blck[2]) 131 | 132 | def rgb2bayer(self, image, outBayerType): 133 | """ 134 | convert rgb image to specified bayer type 135 | :param image: input RGB image 136 | :param outBayerType: output Bayer image 137 | :return: the Bayer image 138 | """ 139 | assert(image.ndim == 3) 140 | assert(len(outBayerType) == 4) 141 | 142 | out = np.zeros((image.shape[0], image.shape[1]), dtype=self.inDataType) 143 | 144 | c = np.zeros(4, dtype=np.uint8) 145 | for i in range(4): 146 | if outBayerType[i] == 'R' or outBayerType[i] == 'r': 147 | c[i] = 0 148 | elif outBayerType[i] == 'G' or outBayerType[i] == 'g': 149 | c[i] = 1 150 | elif outBayerType[i] == 'B' or outBayerType[i] == 'b': 151 | c[i] = 2 152 | 153 | out[::2, ::2] = image[::2,::2, c[0]] 154 | out[::2, 1::2] = image[::2, 1::2, c[1]] 155 | out[1::2, ::2] = image[1::2, ::2, c[2]] 156 | out[1::2, 1::2] = image[1::2, 1::2, c[3]] 157 | return out 158 | 159 | def rgb2bayer3d(self, image, outBayerType): 160 | """ 161 | convert rgb image to specified bayer 3D type 162 | :param image: input RGB image 163 | :param outBayerType: output Bayer image 164 | :return: the Bayer image 165 | """ 166 | 167 | assert (len(outBayerType) == 4) 168 | 169 | if image.ndim == 3: 170 | assert(image.ndim == 3) 171 | out = np.zeros((image.shape[0], image.shape[1], 3), dtype=image.dtype) 172 | 173 | c = np.zeros(4, dtype=np.uint8) 174 | for i in range(4): 175 | if outBayerType[i] == 'R' or outBayerType[i] == 'r': 176 | c[i] = 0 177 | elif outBayerType[i] == 'G' or outBayerType[i] == 'g': 178 | c[i] = 1 179 | elif outBayerType[i] == 'B' or outBayerType[i] == 'b': 180 | c[i] = 2 181 | 182 | out[::2, ::2, c[0]] = image[::2,::2, c[0]] 183 | out[::2, 1::2, c[1]] = image[::2, 1::2, c[1]] 184 | out[1::2, ::2, c[2]] = image[1::2, ::2, c[2]] 185 | out[1::2, 1::2, c[3]] = image[1::2, 1::2, c[3]] 186 | elif image.ndim == 4: 187 | out = np.zeros((image.shape[0], image.shape[1], image.shape[2], 3), dtype=self.inDataType) 188 | c = np.zeros(4, dtype=np.uint8) 189 | for i in range(4): 190 | if outBayerType[i] == 'R' or outBayerType[i] == 'r': 191 | c[i] = 0 192 | elif outBayerType[i] == 'G' or outBayerType[i] == 'g': 193 | c[i] = 1 194 | elif outBayerType[i] == 'B' or outBayerType[i] == 'b': 195 | c[i] = 2 196 | 197 | out[:, ::2, ::2, c[0]] = image[:, ::2, ::2, c[0]] 198 | out[:, ::2, 1::2, c[1]] = image[:, ::2, 1::2, c[1]] 199 | out[:, 1::2, ::2, c[2]] = image[:, 1::2, ::2, c[2]] 200 | out[:, 1::2, 1::2, c[3]] = image[:, 1::2, 1::2, c[3]] 201 | 202 | return out 203 | 204 | def bayer2bayer3d(self, image, inBayerType): 205 | """ 206 | convert bayer image to specified bayer 3D type 207 | :param image: input RGB image 208 | :param inBayerType: input Bayer image 209 | :return: the Bayer image 210 | """ 211 | 212 | assert(image.ndim == 2) 213 | assert(len(inBayerType) == 4) 214 | 215 | out = np.zeros((image.shape[0], image.shape[1], 3), dtype=image.dtype) 216 | 217 | if DEBUG: 218 | print('out.shape = ', out.shape) 219 | 220 | c = np.zeros(4, dtype=np.uint8) 221 | for i in range(4): 222 | if inBayerType[i] == 'R' or inBayerType[i] == 'r': 223 | c[i] = 0 224 | elif inBayerType[i] == 'G' or inBayerType[i] == 'g': 225 | c[i] = 1 226 | elif inBayerType[i] == 'B' or inBayerType[i] == 'b': 227 | c[i] = 2 228 | 229 | out[::2, ::2, c[0]] = image[::2,::2] 230 | out[::2, 1::2, c[1]] = image[::2, 1::2] 231 | out[1::2, ::2, c[2]] = image[1::2, ::2] 232 | out[1::2, 1::2, c[3]] = image[1::2, 1::2] 233 | return out 234 | 235 | def imread(self, path, height=3024, width=4032): 236 | """ 237 | read image from path 238 | :param path: 239 | :param height: only used for raw type 240 | :param width: only used for raw type 241 | :return: the loaded image 242 | """ 243 | if self.inImageType == self.IM_GRAY or self.inImageType == self.IM_RGB or \ 244 | self.inImageType == self.IM_BAYER or self.inImageType == self.IM_BAYER3: 245 | image = cv2.imread(path) 246 | elif self.inImageType == self.IM_TIFF_16: 247 | image = tiff.imread(path) 248 | elif self.inImageType == self.IM_RAW: 249 | image = self.read_raw(path, height, width) 250 | return image 251 | 252 | def process_image(self, image): 253 | """ 254 | convert image from input type to output type 255 | :param image: the input image 256 | :return: the processed image 257 | """ 258 | if self.outImageType == self.IM_GRAY: 259 | if self.inImageType == self.IM_RGB: 260 | out = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) 261 | elif self.inImageType == self.IM_GRAY: 262 | out = image 263 | else: 264 | raise BaseException('Cannot covert image.' + 'Input type : ' + self.inBayerType + ' Out type : Gray') 265 | elif self.outImageType == self.IM_RGB: 266 | assert(image.shape[-1] == 3) 267 | out = image 268 | ####### add bayer type here 269 | elif self.outImageType == self.IM_BAYER or self.outImageType == self.IM_RAW: 270 | if self.inImageType == self.IM_BAYER or self.inImageType == self.IM_RAW: 271 | assert self.inBayerType == self.outBayerType 272 | out = image 273 | elif self.inImageType == self.IM_RGB: 274 | out = self.rgb2bayer(image, self.outBayerType) 275 | elif self.inImageType == self.IM_BAYER3: 276 | out = self.rgb2bayer(image, self.outBayerType) 277 | else: 278 | raise BaseException('Cannot covert image. ' + 'Input type : ' + self.inBayerType + ' Out type : Bayer') 279 | elif self.outImageType == self.IM_BAYER3: 280 | if self.inImageType == self.IM_RGB: 281 | out = self.rgb2bayer3d(image, self.outBayerType) 282 | elif self.inImageType == self.IM_TIFF_16: 283 | # max value 1023, need to divided by 4 284 | image = image / self.unit_norm 285 | image = np.uint8(image) 286 | if image.ndim == 2: 287 | out = self.bayer2bayer3d(image, self.inBayerType) 288 | elif image.ndim == 3: 289 | out = image 290 | else: 291 | raise BaseException('Input image dimension error: got ', image.ndim, ' but expected 2 or 3.') 292 | else: 293 | raise BaseException('Cannot covert image. ' + 'Input type : ' + self.inBayerType + ' Out type : Bayer') 294 | ####### end 295 | 296 | 297 | if self.save_format == self.FMT_LAB: 298 | out = cv2.cvtColor(out, cv2.COLOR_RGB2LAB) 299 | elif self.save_format == self.FMT_YUV: 300 | out = cv2.cvtColor(out, cv2.COLOR_RGB2YUV) 301 | 302 | return out 303 | 304 | 305 | def imwrite(self, path, image): 306 | """ 307 | write image to path 308 | :param path: 309 | :param image: 310 | :return: None 311 | """ 312 | if self.outImageType == self.IM_RAW: 313 | image = image.as_type(np.uint16) 314 | self.write_raw(path, image) 315 | else: 316 | cv2.imwrite(path, image) 317 | 318 | 319 | def list2array(self, list): 320 | """ 321 | convert image list to image array 322 | :param list: 323 | :return: the array 324 | """ 325 | n = len(list) 326 | 327 | assert n > 0 328 | 329 | n_array = 0 330 | for i in range(n): 331 | n_array += list[i].shape[0] 332 | 333 | assert n_array > 0 334 | 335 | array = np.zeros([n_array, list[0].shape[1], list[0].shape[2], list[0].shape[3]]) 336 | 337 | idx = 0 338 | for i in range(n): 339 | array[idx:idx+list[i].shape[0], ...] = list[i] 340 | idx += list[i].shape[0] 341 | return array 342 | 343 | 344 | def _write_data(self, outFile, data, res_data, name, res_name, npart): 345 | array = self.list2array(data) 346 | res_array = self.list2array(res_data) 347 | 348 | if DEBUG: 349 | print('data[0].shape : ', data[0].shape, " array.shape : ", array.shape) 350 | 351 | print('Writing data to hdf5 file ... ') 352 | 353 | if npart > 0: 354 | final_name = '%s_%d' % (name, npart) 355 | final_res_name = '%s_%d' % (res_name, npart) 356 | else: 357 | final_name = name 358 | final_res_name = res_name 359 | 360 | print('name: ', final_name) 361 | print('res_name: ', final_res_name) 362 | 363 | outFile.create_dataset(final_name, data=array, compression='gzip') 364 | outFile.create_dataset(final_res_name, data=res_array, compression='gzip') 365 | 366 | def create_hdf5(self, name, res_name, part_num, max_num=1000): 367 | """ 368 | create a hdf5 image database file from parameters. 369 | :param name: the name of image variable in the file 370 | :return: None 371 | """ 372 | regexp = re.compile(r'.*\.(%s|%s)' % (self.ext.upper(), self.ext.lower()) ) 373 | invalid = [] 374 | data = [] 375 | res_data = [] 376 | n = 0 377 | npart = 0 378 | PART_NUM = part_num # 50 for S7, 20 for mi5s, 100 for wb 379 | MAX_NUM = max_num 380 | 381 | print('Loading images ... ') 382 | outFile = h5py.File(self.outputPath, "w") 383 | 384 | for d, dirs, files in os.walk(self.inputFolder): 385 | for f in files: 386 | if regexp.match(f): 387 | #if n % 1000 == 0: 388 | print('Image', n, ':', f) 389 | try: 390 | im = self.imread(os.path.join(d, f)) 391 | except IOError: 392 | print(' Could not read file : ', f) 393 | invalid.append(os.path.join(d, f)) 394 | continue 395 | 396 | res_im = self.process_image(im) 397 | 398 | if im.ndim == 2: 399 | im = im[..., np.newaxis] 400 | patches = self.cutup(im, [self.patchSize, self.patchSize, 1], [self.stride, self.stride, 1]) 401 | else: 402 | patches = self.cutup(im, [self.patchSize, self.patchSize, im.shape[-1]], [self.stride, self.stride, im.shape[-1]]) 403 | 404 | data.append(patches) 405 | 406 | if res_im.ndim == 2: 407 | res_im = res_im[..., np.newaxis] 408 | res_patches = self.cutup(res_im, [self.patchSize, self.patchSize, 1], [self.stride, self.stride, 1]) 409 | 410 | else: 411 | res_patches = self.cutup(res_im, [self.patchSize, self.patchSize, res_im.shape[-1]], [self.stride, self.stride, res_im.shape[-1]]) 412 | 413 | res_data.append(res_patches) 414 | n += 1 415 | 416 | if n % PART_NUM == 0 and n > 0: 417 | self._write_data(outFile, data, res_data, name, res_name, npart) 418 | 419 | npart += 1 420 | if npart * PART_NUM >= MAX_NUM: 421 | break 422 | 423 | if npart * PART_NUM > MAX_NUM: 424 | break 425 | 426 | 427 | if n > npart * PART_NUM or (n > 0 and npart == 0): 428 | self._write_data(outFile, data, res_data, name, res_name, npart) 429 | npart += 1 430 | 431 | outFile.create_dataset('npart', data=npart) 432 | outFile.close() 433 | 434 | print('Total ', len(invalid), 'invalid files.') 435 | if len(invalid) > 0: 436 | print ('Invalid files : ', invalid) 437 | print('Create database ', name ,' finished.') 438 | 439 | def hdf52folder(self, path, name, savepath, ext='png'): 440 | npart = self.load_hdf5_v1(path, 'npart') 441 | print('npart : ', npart) 442 | # loading training data 443 | 444 | if not os.path.isdir(savepath): 445 | os.mkdir(savepath) 446 | 447 | cnt = 0 448 | for i in range(npart): 449 | print('Data part ', i) 450 | if i > 0: 451 | final_name = '%s_%d' % (name, i) 452 | else: 453 | final_name = name 454 | data = self.load_hdf5_v1(path, final_name) 455 | 456 | l = len(data) 457 | for j in range(l): 458 | cv2.imwrite('%s/%d.%s' % (savepath, cnt, ext), data[j, ...]) 459 | cnt += 1 460 | 461 | 462 | def load_hdf5_v1(self, path, name): 463 | with h5py.File(path, 'r') as inFile: 464 | return inFile[name].value 465 | 466 | def load_hdf5(self, path, name, res_name): 467 | with h5py.File(path, 'r') as inFile: 468 | return inFile[name].value, inFile[res_name].value 469 | 470 | def create_pristine(): 471 | dc = DatabaseCreator('data/pristine_images', 'data/pristine_rgb2gray.h5', \ 472 | inImageType=DatabaseCreator.IM_RGB, outImageType=DatabaseCreator.IM_GRAY, patchSize=128, 473 | stride=128 * 2) 474 | dc.create_hdf5('rgb', 'gray') 475 | 476 | def create_kodak_mcm(): 477 | dc = DatabaseCreator('data/train_kodak', 'data/kodak_rgb2gray.h5', \ 478 | inImageType=DatabaseCreator.IM_RGB, outImageType=DatabaseCreator.IM_GRAY, patchSize=128, 479 | stride=128 * 2) 480 | dc.create_hdf5('rgb', 'gray') 481 | 482 | dc = DatabaseCreator('data/train_mcm', 'data/mcm_rgb2gray.h5', \ 483 | inImageType=DatabaseCreator.IM_RGB, outImageType=DatabaseCreator.IM_GRAY, patchSize=128, 484 | stride=128 * 2) 485 | dc.create_hdf5('rgb', 'gray') 486 | 487 | 488 | if __name__ == '__main__': 489 | create_pristine() 490 | create_kodak_mcm() 491 | 492 | 493 | 494 | 495 | -------------------------------------------------------------------------------- /data_v3.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/data_v3.pyc -------------------------------------------------------------------------------- /drdd_dn_sigma0_50.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | from __future__ import print_function 3 | from torch.autograd import Variable 4 | import torch.nn.functional as F 5 | import torch 6 | import os 7 | from data_v3 import DatabaseCreator 8 | import numpy as np 9 | import time 10 | import tqdm 11 | import argparse 12 | import tifffile as tiff 13 | import re 14 | import cv2 15 | 16 | from network_dn import Network_dn 17 | 18 | 19 | # config 20 | DEBUG = False 21 | 22 | def print_net(net): 23 | for i, weights in enumerate(list(net.parameters())): 24 | print('i:', i, 'weights:', weights.size()) 25 | 26 | 27 | class DeepProcesser: 28 | """ 29 | A class to train and test a tensorflow denoiser. 30 | """ 31 | 32 | # predict_op = [] 33 | def __init__(self, block_depth=4, block_num=5, width = 64, min_noise_level=0, max_noise_level=30, 34 | device = '/gpu:0', batch_size = 32, input_dim = 3, lr=1e-4, use_scalar_noise=True): 35 | self.batchSize = batch_size 36 | self.block_num = block_num 37 | self.block_depth = block_depth 38 | self.width = width 39 | self.min_noise_level = min_noise_level 40 | self.max_noise_level = max_noise_level 41 | self.device = device 42 | self.input_dim = input_dim 43 | self.lr = lr 44 | self.use_scalar_noise=use_scalar_noise 45 | 46 | def train(self, model_dir, trY, valY, maxEpoch=1000, part=0): 47 | """ 48 | train 49 | :param trX: 50 | :param trY: 51 | :param maxEpoch: 52 | :param batchSize: 53 | :return: 54 | """ 55 | 56 | # add new axis for gray image data 57 | if trY.ndim == 3: 58 | trY = trY[..., np.newaxis] 59 | if valY.ndim == 3: 60 | valY = valY[..., np.newaxis] 61 | 62 | # generate model 63 | if not hasattr(self, 'net'): 64 | print('Building training model ...') 65 | net = Network_dn(block_depth=self.block_depth, block_num=self.block_num, width=self.width, 66 | input_dim=self.input_dim, btrain=True) 67 | if torch.cuda.is_available(): 68 | net.cuda() 69 | print_net(net) 70 | optimizer = torch.optim.Adam(net.parameters(), lr=1e-4) 71 | loss_func = F.mse_loss 72 | #loss_func = IspLoss_v2(alpha=0.5) 73 | 74 | # prepare model folder and log file 75 | if not os.path.isdir(model_dir): 76 | os.mkdir(model_dir) 77 | 78 | curEpoch = 0 79 | bestLoss = 99999.0 80 | model_path = model_dir + '/deep_isp.pickle' 81 | log_path = model_dir + '/loss.txt' 82 | 83 | 84 | # restore trainning according to log 85 | if os.path.isfile(log_path): 86 | with open(log_path, 'r') as log_file: 87 | log = log_file.readlines() 88 | if len(log) > 0: 89 | curEpoch = int(log[-1].split(' ')[0]) + 1 + part * maxEpoch 90 | out_file = open(log_path, 'a') 91 | 92 | 93 | if os.path.isfile(model_path): 94 | print('Restored training...') 95 | net.load_state_dict(torch.load(model_path)) 96 | else: 97 | print('Start training...') 98 | 99 | for i in range(curEpoch, maxEpoch): 100 | start_time = time.time() 101 | print('Epoch %d ...' % i) 102 | 103 | train_loss = 0 104 | cnt = 0 105 | # print('len trY : ', len(trY), ' len trX : ', len(trX)) 106 | for start, end in zip(range(0, len(trY), self.batchSize), 107 | range(self.batchSize, len(trY) + 1, self.batchSize)): 108 | 109 | n_level = np.random.rand(1) * (self.max_noise_level - self.min_noise_level) + self.min_noise_level 110 | y = trY[start:end] 111 | y = Variable(torch.from_numpy(y)) 112 | 113 | if torch.cuda.is_available(): 114 | y = y.cuda() 115 | 116 | output = net(y, n_level) 117 | loss = loss_func(output, y) 118 | train_loss += loss 119 | # update weights 120 | net.zero_grad() 121 | loss.backward() 122 | optimizer.step() 123 | cnt += 1 124 | 125 | train_loss /= cnt 126 | if torch.cuda.is_available(): 127 | train_loss = train_loss.cpu() 128 | train_loss = train_loss.data.numpy()[0] 129 | print('train_loss : ', train_loss) 130 | 131 | for n_level in [5]: 132 | val_loss = 0 133 | cnt = 0 134 | for start, end in zip(range(0, len(valY), self.batchSize), 135 | range(self.batchSize, len(valY) + 1, self.batchSize)): 136 | y = valY[start:end] 137 | y = Variable(torch.from_numpy(y), volatile=True) 138 | 139 | if torch.cuda.is_available(): 140 | y = y.cuda() 141 | 142 | output = net(y, n_level / 255.0) 143 | val_loss += loss_func(output, y) 144 | cnt += 1 145 | # prevent too much computation that wastes training time 146 | if cnt > 10: 147 | break 148 | 149 | # print loss 150 | val_loss /= cnt 151 | 152 | if torch.cuda.is_available(): 153 | val_loss = val_loss.cpu() 154 | 155 | val_loss = val_loss.data.numpy()[0] 156 | 157 | print('noise_level : ', n_level, ' val_loss : ', val_loss) 158 | print(i, n_level, train_loss, val_loss, file=out_file) 159 | 160 | print('time : ', time.time() - start_time, ' s') 161 | 162 | 163 | 164 | if i % 10 == 0 and i < maxEpoch * 4 / 5: 165 | torch.save(net.state_dict(), model_path) 166 | print('Model saved') 167 | if val_loss < bestLoss: 168 | bestLoss = val_loss 169 | print('Best Loss ', bestLoss) 170 | out_file.flush() 171 | 172 | if i > maxEpoch * 4 / 5 and val_loss < bestLoss: 173 | bestLoss = val_loss 174 | torch.save(net.state_dict(), model_path) 175 | print('Model saved') 176 | print('Best Loss ', bestLoss) 177 | 178 | out_file.close() 179 | print('Best Val Loss ', bestLoss) 180 | 181 | 182 | def load_model(self, model_dir, btrain=False): 183 | print('Building model ...') 184 | net = Network_dn(self.block_depth, self.block_num, self.width, self.input_dim, btrain=btrain) 185 | #print('block_num : ', self.block_num, ' block_depth : ', self.block_depth) 186 | print('Loading model ...') 187 | net.load_state_dict(torch.load('%s/deep_isp.pickle' % model_dir)) 188 | if torch.cuda.is_available(): 189 | net.cuda() 190 | self.net = net 191 | print_net(net) 192 | 193 | def test(self, image, noise_level, psize, crop): 194 | """ 195 | denoise a bayer image, whose pixels values are in [0, 1] 196 | :param image the image to be denoised 197 | :param psize: size of patch 198 | :param crop: crop of image patch 199 | :return: 200 | """ 201 | assert image.ndim == 3 202 | start_time = time.time() 203 | 204 | h, w = image.shape[:2] 205 | 206 | psize = min(min(psize, h), w) 207 | psize -= psize % 2 208 | 209 | # psize = 1024 210 | 211 | patch_step = psize 212 | patch_step -= 2 * crop 213 | # patch_step = 4096 214 | shift_factor = 2 215 | 216 | # Result array 217 | R = np.zeros([image.shape[0], image.shape[1], 3], dtype=np.float32) 218 | 219 | rangex = range(0, w - 2 * crop, patch_step) 220 | rangey = range(0, h - 2 * crop, patch_step) 221 | ntiles = len(rangex) * len(rangey) 222 | 223 | image = np.float32(image) 224 | 225 | with tqdm.tqdm(total=ntiles, unit='tiles', unit_scale=True) as pbar: 226 | for start_x in rangex: 227 | for start_y in rangey: 228 | a_time = time.time() 229 | 230 | end_x = start_x + psize 231 | end_y = start_y + psize 232 | if end_x > w: 233 | end_x = w 234 | end_x = shift_factor * ((end_x) / shift_factor) 235 | start_x = end_x - psize 236 | if end_y > h: 237 | end_y = h 238 | end_y = shift_factor * ((end_y) / shift_factor) 239 | start_y = end_y - psize 240 | 241 | tileM = image[np.newaxis, start_y:end_y, start_x:end_x, :] 242 | tileM = tileM.transpose(0, 3, 1, 2) 243 | tileM = Variable(torch.from_numpy(tileM)) 244 | if torch.cuda.is_available(): 245 | tileM = tileM.cuda() 246 | 247 | if DEBUG: 248 | print('tileM.shape : ', tileM.shape) 249 | 250 | b_time = time.time() 251 | 252 | if self.use_scalar_noise: 253 | out = self.net(tileM, noise_level, self.use_scalar_noise) 254 | #if True: 255 | # out = self.net(tileM, 5.0 / 255.0, True) 256 | else: 257 | noise = noise_level[:, :, start_y:end_y, start_x:end_x] 258 | #noise = np.ones((noise.shape[0], noise.shape[1], noise.shape[2], noise.shape[3]), dtype=np.float32) * 5.0 / 255.0 259 | out = self.net(tileM, noise, self.use_scalar_noise) 260 | 261 | 262 | c_time = time.time() 263 | 264 | if torch.cuda.is_available(): 265 | out = out.data.cpu() 266 | else: 267 | out = out.data 268 | 269 | out = out.numpy().transpose(0, 2, 3, 1) 270 | out = out[0, ...] 271 | 272 | s = out.shape[0] 273 | R[start_y + crop:start_y + crop + s, 274 | start_x + crop:start_x + crop + s, :] = out 275 | 276 | d_time = time.time() 277 | 278 | pbar.update(1) 279 | 280 | if DEBUG: 281 | print('image crop : ', (b_time - a_time) * 1000, ' ms') 282 | print('forward : ', (c_time - b_time) * 1000, ' ms') 283 | print('put patch back :', (d_time - c_time) * 1000, ' ms') 284 | 285 | R[R < 0] = 0.0 286 | R[R > 1] = 1.0 287 | 288 | runtime = (time.time() - start_time) * 1000 # in ms 289 | 290 | return R, runtime 291 | 292 | 293 | 294 | def mem_divide(x, divider): 295 | # a memory efficient divide function 296 | # when x is huge, this method saves memory 297 | 298 | for i in range(0, x.shape[0]): 299 | x[i,...] = x[i, ...] / divider 300 | return x 301 | 302 | 303 | def train(modelPath, trainPathY, valPathY, block_num, block_depth, width, minNoiseLevel, maxNoiseLevel, device='0'): 304 | """ 305 | Training using Denoiser class. 306 | :param modelPath: path to save trained model 307 | :param trainPath: path to training dataset 308 | :param valPath: path to validation dataset 309 | :param feature_dim: width of the DNN 310 | :param depth: depth of the DNN 311 | :param minNoiseLevel: minimum noise level added to clean images 312 | :param maxNoiseLevel: maximum noise level added to clean images 313 | :param device: which GPU to use (for machines with multiple GPUs, this avoid taking up all GPUs) 314 | :return: Null 315 | """ 316 | os.environ['CUDA_VISIBLE_DEVICES'] = device 317 | deepProcesser = DeepProcesser(block_depth=block_depth, block_num=block_num, width=width, 318 | min_noise_level=minNoiseLevel, max_noise_level=maxNoiseLevel, device='/gpu:0') 319 | 320 | dc = DatabaseCreator() 321 | nameY = 'rgb' 322 | # res_name = 'gray' 323 | maxEpoch = 1000 324 | 325 | npart = dc.load_hdf5_v1(trainPathY, 'npart') 326 | print('npart : ', npart) 327 | # loading validation data 328 | 329 | final_nameY = '%s_%d' % (nameY, npart - 1) 330 | 331 | valY = dc.load_hdf5_v1(trainPathY, final_nameY) 332 | 333 | valY = valY[:deepProcesser.batchSize, ...] 334 | 335 | valY = mem_divide(valY, 255.0) 336 | 337 | # change dims and float64 to float32 for pytorch 338 | valY = np.float32(valY.transpose(0, 3, 1, 2)) 339 | 340 | curEpoch = 0 341 | if os.path.isfile(modelPath + '/loss.txt'): 342 | with open(modelPath + '/loss.txt', 'r') as log_file: 343 | log = log_file.readlines() 344 | if len(log) > 0: 345 | curEpoch = int(log[-1].split(' ')[0]) 346 | # loading training data 347 | for i in range((curEpoch + 1) / (maxEpoch / (npart - 1)), npart - 1): 348 | print('Data part ', i) 349 | if i > 0: 350 | final_nameY = '%s_%d' % (nameY, i) 351 | else: 352 | final_nameY = nameY 353 | 354 | trY = dc.load_hdf5_v1(trainPathY, final_nameY) 355 | trY = mem_divide(trY, 255.0) 356 | 357 | # change dims and float64 to float32 for pytorch 358 | trY = np.float32(trY.transpose(0, 3, 1, 2)) 359 | 360 | deepProcesser.train(modelPath, trY, valY, maxEpoch=maxEpoch / (npart - 1) * (i + 1)) 361 | 362 | def test(model_dir, block_num, width, block_depth, device, noise, outfile, use_scalar_noise=True): 363 | """ 364 | Denoise noisy images using Denoiser class with pre-trained model. 365 | :param modelPath: path to save trained model 366 | :param device: which GPU to use (for machines with multiple GPUs, this avoid taking up all GPUs) 367 | :param noise: standard variation of noise of the tested images 368 | :return: 369 | """ 370 | os.environ['CUDA_VISIBLE_DEVICES'] = device 371 | deepProcesser = DeepProcesser(block_num=block_num, width=width, block_depth=block_depth,use_scalar_noise=use_scalar_noise) 372 | deepProcesser.load_model(model_dir, False) 373 | 374 | regexp = re.compile(r'.*\.(%s)' % '(tif|tiff|jpg|png)') 375 | inputFolder = 'data/medical' 376 | 377 | psize = 200 378 | noise_level = noise / 255.0 379 | max_value = 255.0 380 | 381 | crop = 0 382 | n = 0 383 | 384 | #dc = DatabaseCreator(inBayerType='grbg', outBayerType='grbg') 385 | 386 | for d, dirs, files in os.walk(inputFolder): 387 | for f in files: 388 | if regexp.match(f): 389 | print('image', n, f) 390 | image = cv2.imread(os.path.join(d, f)) 391 | 392 | if DEBUG: 393 | print ('image.shape : ', image.shape) 394 | 395 | image = image / max_value 396 | R, runtime = deepProcesser.test(image, noise_level, psize, crop) 397 | out = np.uint8(R * 255 + 0.5) 398 | 399 | #R = swap_blue_red(R) 400 | 401 | if DEBUG: 402 | print('max value = ', np.max(np.abs(R))) 403 | print('time : ', runtime, ' ms') 404 | cv2.imwrite(outfile, out) 405 | with open('data/time.txt', 'w') as out_file: 406 | print(runtime, file=out_file) 407 | n += 1 408 | 409 | if __name__ == '__main__': 410 | ## configuration 411 | bTrain = True 412 | modelPath = 'dn_sigma0_50' 413 | block_num = 5 414 | block_depth = 4 415 | width = 64 416 | device = '0' 417 | minNoiseLevel = 0.0 / 255.0 418 | maxNoiseLevel = 50.0 / 255.0 419 | #### end configuration 420 | 421 | if bTrain: 422 | train('models/%s' % modelPath, '/Volumes/文档/实验数据/Denoiser/pristine_rgb2gray.h5', 423 | '/Volumes/文档/实验数据/Denoiser/kodak_rgb2gray.h5', block_num, block_depth, width, minNoiseLevel, 424 | maxNoiseLevel, device=device) 425 | else: 426 | parser = argparse.ArgumentParser() 427 | parser.add_argument('--noise', type=float, default=0.0, 428 | help='standard deviation of additive Gaussian noise, w.r.t to a [0,1] intensity scale.') 429 | 430 | parser.add_argument('--model_name', type=str, default=None, help='path to model') 431 | parser.add_argument('--outfile', type=str, default=None, help='path to model') 432 | parser.add_argument('--gpu', type=int, default=1, help='use GPU or not') 433 | 434 | args = parser.parse_args() 435 | 436 | if not args.gpu == 1: 437 | device = '' 438 | 439 | print('model_name : ', args.model_name) 440 | print('use_gpu : ', args.gpu) 441 | 442 | args.outfile = 'test_res.png' 443 | args.noise = 8 444 | 445 | #test('DRDD_pytorch/models/%s' % modelPath, block_num, width, block_depth, device=device, noise=args.noise, 446 | # outfile=args.outfile) 447 | test('models/%s' % modelPath, block_num, width, block_depth, device=device, noise=args.noise, 448 | outfile=args.outfile) 449 | 450 | 451 | 452 | 453 | -------------------------------------------------------------------------------- /evaluate.py: -------------------------------------------------------------------------------- 1 | # coding=utf8 2 | # Author: TomHeaven, hanlin_tan@nudt.edu.cn, 2018.06.27 3 | 4 | from __future__ import print_function 5 | import cv2 6 | import re 7 | import os 8 | 9 | import numpy as np 10 | import math 11 | 12 | 13 | def get_psnr(img1, img2): 14 | mse = np.mean( (img1 - img2) ** 2 ) 15 | if mse == 0: 16 | return 100 17 | PIXEL_MAX = 255.0 18 | return 20 * math.log10(PIXEL_MAX / math.sqrt(mse)) 19 | 20 | 21 | def compare_results(folder1, folder2): 22 | regexp = re.compile(r'.*\.(%s)' % '(jpg)|(png)|(bmp)|(tif)') 23 | 24 | n = 0 25 | 26 | psnr_list = [] 27 | for d, dirs, files in os.walk(folder1): 28 | for f in files: 29 | if regexp.match(f): 30 | image1 = cv2.imread(os.path.join(folder1, f)) 31 | 32 | # for bsd500 (.jpg) 33 | if f.endswith('.jpg'): 34 | f = f.replace('.jpg', '.png') 35 | image2 = cv2.imread(os.path.join(folder2, f)) 36 | psnr = get_psnr(image1, image2) 37 | psnr_list.append(psnr) 38 | 39 | psnr_array = np.asarray(psnr_list) 40 | avg_psnr = psnr_array.mean() 41 | return avg_psnr, psnr_array 42 | 43 | def compare_all(): 44 | methods = ['drne+dn', 'chen+dn'] 45 | #datasets = ['kodak', 'mcm', 'bsd500'] 46 | #methods = ['chen+dn'] 47 | datasets = ['kodak'] 48 | #sigmas = [5, 15, 25] 49 | sigmas = [15] 50 | 51 | 52 | for m in methods: 53 | print('Method : ', m) 54 | for d in datasets: 55 | print(' Dataset : ', d) 56 | 57 | folder1 = 'data/%s' % d 58 | for s in sigmas: 59 | print(' Sigma : ', s) 60 | 61 | folder2 = 'res/%s/%s_sigma%d' % (m, d, s) 62 | 63 | avg_psnr, psnr_array = compare_results(folder1, folder2) 64 | print(' average psnr : ', avg_psnr) 65 | 66 | if __name__ == '__main__': 67 | compare_all() 68 | -------------------------------------------------------------------------------- /generate_noisy_images.py: -------------------------------------------------------------------------------- 1 | # coding=utf8 2 | # Author: TomHeaven, hanlin_tan@nudt.edu.cn, 2018.06.27 3 | 4 | from __future__ import print_function 5 | 6 | import cv2 7 | import re 8 | import os 9 | import numpy as np 10 | import math 11 | 12 | 13 | def add_noise(input_folder, output_folder, sigma, is_homo=True): 14 | regexp = re.compile(r'.*\.(%s)' % '(jpg)|(png)|(bmp)|(tif)') 15 | 16 | if not os.path.isdir(output_folder): 17 | os.mkdir(output_folder) 18 | 19 | n = 0 20 | for d, dirs, files in os.walk(input_folder): 21 | for f in files: 22 | if regexp.match(f): 23 | print('image', n, f) 24 | 25 | image = cv2.imread(os.path.join(d, f)) 26 | image = np.float32(image) 27 | 28 | if is_homo: 29 | s = sigma 30 | else: 31 | s = (np.random.rand(1) - 0.5) * 5 + sigma 32 | noisy = image + np.random.randn(image.shape[0], image.shape[1], image.shape[2]) * s 33 | # clip is very important 34 | noisy = np.uint8(np.clip(noisy, 0, 255)) 35 | 36 | if f.endswith('.jpg'): 37 | f = f.replace('.jpg', '.png') 38 | 39 | cv2.imwrite(os.path.join(output_folder, f), noisy) 40 | n += 1 41 | 42 | def add_noise_v2(input_folder, output_folder, sigma, min_noise_level=0, max_noise_level=30): 43 | regexp = re.compile(r'.*\.(%s)' % '(jpg)|(png)|(bmp)|(tif)') 44 | 45 | if not os.path.isdir(output_folder): 46 | os.mkdir(output_folder) 47 | 48 | n = 0 49 | for d, dirs, files in os.walk(input_folder): 50 | for f in files: 51 | if regexp.match(f): 52 | print('image', n, f) 53 | 54 | image = cv2.imread(os.path.join(d, f)) 55 | image = np.float32(image) 56 | 57 | 58 | s = np.random.rand(1) * (max_noise_level - min_noise_level) + min_noise_level 59 | noisy = image + np.random.randn(image.shape[0], image.shape[1], image.shape[2]) * s 60 | # clip is very important 61 | noisy = np.uint8(np.clip(noisy, 0, 255)) 62 | 63 | if f.endswith('.jpg'): 64 | f = f.replace('.jpg', '.png') 65 | 66 | cv2.imwrite(os.path.join(output_folder, f), noisy) 67 | n += 1 68 | 69 | def add_noise_v3(input_folder, output_folder, sigma, min_noise_level=0, max_noise_level=15): 70 | regexp = re.compile(r'.*\.(%s)' % '(jpg)|(png)|(bmp)|(tif)') 71 | 72 | if not os.path.isdir(output_folder): 73 | os.mkdir(output_folder) 74 | 75 | n = 0 76 | 77 | for d, dirs, files in os.walk(input_folder): 78 | for f in files: 79 | if regexp.match(f): 80 | print('image', n, f) 81 | 82 | image = cv2.imread(os.path.join(d, f)) 83 | gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) 84 | 85 | image = np.float32(image) 86 | #gray = np.float32(gray) 87 | 88 | sigma_s = np.random.rand(1) * 3.5 89 | sigma_r = np.random.rand(1) * (max_noise_level - min_noise_level) + min_noise_level 90 | 91 | s = np.sqrt(sigma_s**2 + sigma_r * image) 92 | # Prevent s from exceeding prediction range of DRNE 93 | s = np.clip(s, 0, 30) 94 | noisy = image + np.random.randn(image.shape[0], image.shape[1], image.shape[2]) * s 95 | # clip is very important 96 | noisy = np.uint8(np.clip(noisy, 0, 255)) 97 | 98 | if f.endswith('.jpg'): 99 | f = f.replace('.jpg', '.png') 100 | 101 | cv2.imwrite(os.path.join(output_folder, f), noisy) 102 | n += 1 103 | 104 | # 分段非均匀 105 | def generate_noisy_datasets(is_homo): 106 | add_noise('data/mcm', 'data/mcm_sigma5', 5, is_homo) 107 | add_noise('data/mcm', 'data/mcm_sigma15', 15, is_homo) 108 | add_noise('data/mcm', 'data/mcm_sigma25', 25, is_homo) 109 | 110 | add_noise('data/kodak', 'data/kodak_sigma5', 5, is_homo) 111 | add_noise('data/kodak', 'data/kodak_sigma15', 15, is_homo) 112 | #add_noise('data/kodak', 'data/kodak_sigma25', 25, is_homo) 113 | 114 | add_noise('data/bsd500', 'data/bsd500_sigma5', 5, is_homo) 115 | add_noise('data/bsd500', 'data/bsd500_sigma15', 15, is_homo) 116 | add_noise('data/bsd500', 'data/bsd500_sigma25', 25, is_homo) 117 | 118 | # 0-30 非均匀 119 | def generate_noisy_datasets_v2(): 120 | add_noise_v2('data/mcm', 'data/mcm_sigma15', 15) 121 | add_noise_v2('data/kodak', 'data/kodak_sigma15', 15) 122 | add_noise_v2('data/bsd500', 'data/bsd500_sigma15', 15) 123 | 124 | # Real noise model 非均匀 125 | def generate_noisy_datasets_v3(): 126 | add_noise_v3('data/mcm', 'data/mcm_sigma15', 15) 127 | add_noise_v3('data/kodak', 'data/kodak_sigma15', 15) 128 | add_noise_v3('data/bsd500', 'data/bsd500_sigma15', 15) 129 | 130 | 131 | 132 | if __name__ == '__main__': 133 | ####### 134 | # Use only one of the following functions at one time 135 | ####### 136 | 137 | # to generate homogeneous noise 138 | #generate_noisy_datasets(is_homo=True) 139 | 140 | # to generate non-homogeneous noise in three ranges: [0, 9], [10, 19], [20, 29] 141 | #generate_noisy_datasets(is_homo=False) 142 | 143 | # to generate non-homogeneous noise in range: [0, 29] 144 | #generate_noisy_datasets_v2() 145 | 146 | # to genereate non-homogeneous using noise model (1) 147 | generate_noisy_datasets_v3() 148 | -------------------------------------------------------------------------------- /matlab/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/matlab/.DS_Store -------------------------------------------------------------------------------- /matlab/Chen_ICCV2015_code/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/matlab/Chen_ICCV2015_code/.DS_Store -------------------------------------------------------------------------------- /matlab/Chen_ICCV2015_code/Demo.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- 2 | % 3 | % Last revision: 1-Dec-2015 4 | % 5 | % Authors: Guangyong Chen 6 | % License: MIT License 7 | % 8 | % Copyright (c) 2015 Guangyong Chen 9 | % 10 | % Permission is hereby granted, free of charge, to any person obtaining 11 | % a copy of this software and associated documentation files (the 12 | % "Software"), to deal in the Software without restriction, including 13 | % without limitation the rights to use, copy, modify, merge, publish, 14 | % distribute, sublicense, and/or sell copies of the Software, and to 15 | % permit persons to whom the Software is furnished to do so, subject to 16 | % the following conditions: 17 | % 18 | % The above copyright notice and this permission notice shall be 19 | % included in all copies or substantial portions of the Software. 20 | % 21 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22 | % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23 | % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 24 | % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 25 | % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 26 | % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | % 29 | % ----------------------------------------------------------------------- 30 | clc;clear;close all; 31 | addpath(genpath('./')); 32 | fileList = dir('./imdata/*.jpg'); 33 | 34 | SigmaCnt = 1; 35 | SigVariance = []; 36 | for givsigma = 10:10:50 37 | 38 | for ImCnt = 1: numel(fileList) 39 | im = double(imread(fileList(ImCnt).name)); 40 | im_noisy = im + +randn(size(im))*givsigma; 41 | 42 | estsigma =NoiseEstimation(im_noisy, 8); 43 | 44 | disp(strcat('gnd:',num2str(givsigma),'-Estimated:',num2str(estsigma))); 45 | end 46 | end 47 | 48 | 49 | -------------------------------------------------------------------------------- /matlab/Chen_ICCV2015_code/NoiseEstimation.m: -------------------------------------------------------------------------------- 1 | % ----------------------------------------------------------------------- 2 | %Inputs: 3 | % im_noisy: the noisy image whose noise level requires to be estimated 4 | % PatchSize: the predefined size of patches 5 | % 6 | %Outputs: 7 | % estsigma: Estimated result given by our method 8 | % 9 | % Last revision: 1-Dec-2015 10 | % 11 | % Authors: Guangyong Chen 12 | % License: MIT License 13 | % 14 | % Copyright (c) 2015 Guangyong Chen 15 | % 16 | % Permission is hereby granted, free of charge, to any person obtaining 17 | % a copy of this software and associated documentation files (the 18 | % "Software"), to deal in the Software without restriction, including 19 | % without limitation the rights to use, copy, modify, merge, publish, 20 | % distribute, sublicense, and/or sell copies of the Software, and to 21 | % permit persons to whom the Software is furnished to do so, subject to 22 | % the following conditions: 23 | % 24 | % The above copyright notice and this permission notice shall be 25 | % included in all copies or substantial portions of the Software. 26 | % 27 | % THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 28 | % EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 29 | % MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 30 | % NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 31 | % LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 32 | % OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 33 | % WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 34 | % 35 | % ----------------------------------------------------------------------- 36 | function estsigma =NoiseEstimation(im_noisy,PatchSize) 37 | 38 | p_out = image2cols(im_noisy, PatchSize, 3); 39 | 40 | mu = mean(p_out,2); 41 | sigma=(p_out-repmat(mu,[1,size(p_out,2)])) ... 42 | *(p_out-repmat(mu,[1,size(p_out,2)]))'/(size(p_out,2)); 43 | eigvalue = (sort((eig(sigma)),'ascend')); 44 | 45 | for CompCnt = size(p_out,1):-1:1 46 | Mean = mean(eigvalue(1:CompCnt)); 47 | 48 | if(sum(eigvalue(1:CompCnt)>Mean) == sum(eigvalue(1:CompCnt) 0: 118 | curEpoch = int(log[-1].split(' ')[0]) + 1 + part * maxEpoch 119 | 120 | out_file = open(saveDir + '/loss.txt', 'a') 121 | with tf.Session() as sess: 122 | self.sess = sess 123 | 124 | with tf.device(self.device): 125 | ckpt = tf.train.get_checkpoint_state(saveDir) 126 | if ckpt and ckpt.model_checkpoint_path: 127 | print('Restored training...') 128 | saver.restore(sess, saveDir + '/tf_estimator.ckpt') 129 | else: 130 | print('Start training...') 131 | # init all variables 132 | tf.global_variables_initializer().run() 133 | 134 | for i in range(curEpoch, maxEpoch): 135 | start_time = time.time() 136 | print('Epoch %d ...' % i) 137 | for start, end in zip(range(0, len(trY), self.batchSize), 138 | range(self.batchSize, len(trY) + 1, self.batchSize)): 139 | 140 | y = trY[start:end] 141 | 142 | n_level = np.random.rand(1) * (maxNoiseLevel - minNoiseLevel) + minNoiseLevel 143 | 144 | sess.run(self.train_op, feed_dict={self.x: y, self.noise_level: n_level}) 145 | 146 | # print loss 147 | for n_level in [5, 15, 25]: 148 | loss = sess.run(self.cost, feed_dict={self.x: trY[:self.batchSize, ...], 149 | self.noise_level: [n_level / 255.0]}) 150 | val_loss = sess.run(self.cost, feed_dict={self.x: valY[:self.batchSize, ...], 151 | self.noise_level: [n_level / 255.0]}) 152 | print('loss n : ', n_level, loss, ' val loss : ', val_loss) 153 | print(i, n_level, loss, val_loss, file=out_file) 154 | print('time : ', time.time() - start_time, ' s') 155 | 156 | 157 | if i % 10 == 0: 158 | if val_loss < bestLoss or i < maxEpoch * 4 / 5: 159 | bestLoss = val_loss 160 | saver.save(sess, saveDir + '/tf_estimator.ckpt') 161 | print('Model saved') 162 | print('Best Loss ', bestLoss) 163 | out_file.flush() 164 | 165 | if i > maxEpoch * 4 / 5 and val_loss < bestLoss: 166 | bestLoss = val_loss 167 | saver.save(sess, saveDir + '/tf_estimator.ckpt') 168 | print('Model saved') 169 | print('Best Loss ', bestLoss) 170 | 171 | out_file.close() 172 | print('Best Loss ', bestLoss) 173 | 174 | 175 | def load_model(self, saveDir, batchSize=1, xshape=[128, 128, 1], yshape=[128, 128, 3]): 176 | # init model 177 | # generate model 178 | self.batchSize = batchSize 179 | self.xshape = xshape 180 | self.yshape = yshape 181 | self.predict_op, self.x = self.build_model(bTrain=False) 182 | saver = tf.train.Saver() 183 | 184 | config = tf.ConfigProto() 185 | config.gpu_options.allow_growth = True # dynamically grow the memory used on the GPU 186 | sess = tf.Session(config=config) 187 | with tf.device(self.device): 188 | ckpt = tf.train.get_checkpoint_state(saveDir) 189 | if ckpt and ckpt.model_checkpoint_path: 190 | print('loading model ...') 191 | saver.restore(sess, saveDir + '/tf_denoiser.ckpt') 192 | self.sess = sess 193 | 194 | def denoise_bayer(self, image, psize, crop): 195 | """ 196 | denoise a bayer image, whose pixels values are in [0, 1] 197 | :param image the image to be denoised 198 | :param noise: estimated noise level of the image 199 | :param psize: size of patch 200 | :param crop: crop of image patch 201 | :return: 202 | """ 203 | assert image.ndim == 3 204 | start_time = time.time() 205 | 206 | h, w = image.shape[:2] 207 | 208 | psize = min(min(psize, h), w) 209 | psize -= psize % 2 210 | 211 | # psize = 1024 212 | 213 | patch_step = psize 214 | patch_step -= 2 * crop 215 | # patch_step = 4096 216 | shift_factor = 2 217 | 218 | # Result array 219 | R = np.zeros([image.shape[0], image.shape[1], 3], dtype=np.float32) 220 | 221 | rangex = range(0, w - 2 * crop, patch_step) 222 | rangey = range(0, h - 2 * crop, patch_step) 223 | ntiles = len(rangex) * len(rangey) 224 | 225 | #image = image[..., np.newaxis] 226 | 227 | # resize input 228 | sess = self.sess 229 | with tf.device(self.device): 230 | with tqdm.tqdm(total=ntiles, unit='tiles', unit_scale=True) as pbar: 231 | for start_x in rangex: 232 | for start_y in rangey: 233 | a_time = time.time() 234 | 235 | end_x = start_x + psize 236 | end_y = start_y + psize 237 | if end_x > w: 238 | end_x = w 239 | end_x = shift_factor * ((end_x) / shift_factor) 240 | start_x = end_x - psize 241 | if end_y > h: 242 | end_y = h 243 | end_y = shift_factor * ((end_y) / shift_factor) 244 | start_y = end_y - psize 245 | 246 | tileM = image[np.newaxis, start_y:end_y, start_x:end_x, :] 247 | if DEBUG: 248 | print('tileM.shape : ', tileM.shape) 249 | 250 | b_time = time.time() 251 | out = sess.run(self.predict_op, feed_dict={self.x: tileM }) 252 | c_time = time.time() 253 | 254 | out = out.reshape(out.shape[1], out.shape[2], 1) 255 | s = out.shape[0] 256 | R[start_y + crop:start_y + crop + s, 257 | start_x + crop:start_x + crop + s, :] = out 258 | 259 | d_time = time.time() 260 | 261 | pbar.update(1) 262 | 263 | if DEBUG: 264 | print('image crop : ', (b_time - a_time) * 1000, ' ms') 265 | print('forward : ', (c_time - b_time) * 1000, ' ms') 266 | print('put patch back :', (d_time - c_time) * 1000, ' ms') 267 | 268 | R[R < 0] = 0.0 269 | R[R > 1] = 1.0 270 | 271 | runtime = (time.time() - start_time) * 1000 # in ms 272 | 273 | return R, runtime 274 | 275 | 276 | ####################################################### 277 | # Functions to call Estimator 278 | 279 | def mem_divide(x, divider): 280 | # a memory efficient divide function 281 | # when x is huge, this method saves memory 282 | 283 | for i in range(0, x.shape[0]): 284 | x[i,...] = x[i, ...] / divider 285 | return x 286 | 287 | 288 | def train(modelPath, trainPath, valPath, feature_dim, depth, minNoiseLevel, maxNoiseLevel, x_shape=[128,128,1], y_shape=[128,128,3], device='0'): 289 | """ 290 | Training using Estimator class. 291 | :param modelPath: path to save trained model 292 | :param trainPath: path to training dataset 293 | :param valPath: path to validation dataset 294 | :param feature_dim: width of the DNN 295 | :param depth: depth of the DNN 296 | :param minNoiseLevel: minimum noise level added to clean images 297 | :param maxNoiseLevel: maximum noise level added to clean images 298 | :param x_shape: Input patch size 299 | :param y_shape: Output patch size 300 | :param device: which GPU to use (for machines with multiple GPUs, this avoid taking up all GPUs) 301 | :return: Null 302 | """ 303 | os.environ['CUDA_VISIBLE_DEVICES'] = device 304 | estimator = Estimator(device='/gpu:0', depth= depth, feature_dim=feature_dim, xshape=x_shape, yshape=y_shape) 305 | 306 | dc = DatabaseCreator() 307 | 308 | name = 'rgb' 309 | # res_name = 'gray' 310 | maxEpoch = 3000 311 | 312 | valY = dc.load_hdf5_v1(valPath, name) 313 | valY = valY[:estimator.batchSize, ...] 314 | 315 | valY = mem_divide(valY, 255.0) 316 | 317 | npart = dc.load_hdf5_v1(trainPath, 'npart') 318 | 319 | curEpoch = 0 320 | if os.path.isfile(modelPath + '/loss.txt'): 321 | with open(modelPath + '/loss.txt', 'r') as log_file: 322 | log = log_file.readlines() 323 | if len(log) > 0: 324 | curEpoch = int(log[-1].split(' ')[0]) 325 | 326 | for i in range((curEpoch+1) / (maxEpoch/npart), npart): 327 | #for i in range(0, 1): 328 | print('Data part ', i) 329 | if i > 0: 330 | final_name = '%s_%d' % (name, i) 331 | #final_res_name = '%s_%d' % (res_name, i) 332 | else: 333 | final_name = name 334 | #final_res_name = res_name 335 | 336 | trY = dc.load_hdf5_v1(trainPath, final_name) 337 | trY = mem_divide(trY, 255.0) 338 | 339 | estimator.train(modelPath, trY, valY, minNoiseLevel, maxNoiseLevel, maxEpoch=maxEpoch / npart * (i+1)) 340 | #estimator.train(modelPath, trY, valY, minNoiseLevel, maxNoiseLevel, maxEpoch=maxEpoch) 341 | 342 | # estimator.sess.close() 343 | 344 | def test(modelPath, feature_dim, depth, device, noise): 345 | """ 346 | Denoise noisy images using Estimator class with pre-trained model. 347 | :param modelPath: path to save trained model 348 | :param feature_dim: width of the DNN 349 | :param depth: depth of the DNN 350 | :param device: which GPU to use (for machines with multiple GPUs, this avoid taking up all GPUs) 351 | :param noise: standard variation of noise of the tested images 352 | :return: 353 | """ 354 | os.environ['CUDA_VISIBLE_DEVICES'] = device 355 | estimator = Estimator(batchSize=1, feature_dim=feature_dim, depth=depth) 356 | regexp = re.compile(r'.*\.(%s)' % '(jpg)|(png)|(bmp)|(tif)') 357 | inputFolder = 'data/mcm' 358 | 359 | psize = 500 360 | noise_level = noise / 255.0 361 | 362 | print('true noise : ', noise) 363 | max_value = 255.0 364 | 365 | crop = 0 366 | n = 0 367 | 368 | avg_en = 0 369 | 370 | for d, dirs, files in os.walk(inputFolder): 371 | for f in files: 372 | if regexp.match(f): 373 | print('image', n, f) 374 | 375 | image = cv2.imread(os.path.join(d, f)) 376 | #image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) 377 | #cv2.imwrite('%s/%s_rgb.png' % ('output', f), image) 378 | 379 | image = image + np.random.randn(image.shape[0], image.shape[1], image.shape[2]) * noise 380 | 381 | if DEBUG: 382 | print ('image.shape : ', image.shape) 383 | 384 | if n == 0: 385 | xshape = [psize, psize, 3] 386 | yshape = [psize, psize, 3] 387 | estimator.load_model(modelPath, batchSize=1, xshape = xshape, yshape=yshape) 388 | 389 | #cv2.imwrite('%s/%s_in.bmp' % ('output', f), np.uint8(image / max_value * 255.0 + 0.5)) 390 | image = image / max_value 391 | 392 | 393 | #cv2.imwrite('%s/%s_in.png' % ('output', f), np.uint8(image * 255 + 0.5)) 394 | 395 | R, runtime = estimator.denoise_bayer(image, psize, crop) 396 | out = np.uint8(R * 255 + 0.5) 397 | 398 | estimated_noise = np.mean(np.mean(np.mean(R, axis=0), axis=0), axis=0) 399 | 400 | if DEBUG: 401 | print('max value = ', np.max(np.abs(R))) 402 | print('time : ', runtime, ' ms') 403 | 404 | #cv2.imwrite('data/dnn_res.bmp', out) 405 | 406 | print('estimate_noise : ', estimated_noise * 255.0) 407 | cv2.imwrite('%s/%s.png' % ('output', f), out) 408 | with open('data/time.txt', 'w') as out_file: 409 | print(runtime, file=out_file) 410 | n += 1 411 | avg_en += estimated_noise 412 | 413 | print('avg_en : ', avg_en / n * 255.0) 414 | estimator.sess.close() 415 | 416 | def test_real(modelPath, feature_dim, depth, device): 417 | """ 418 | Denoise noisy images using Estimator class with pre-trained model. 419 | :param modelPath: path to save trained model 420 | :param feature_dim: width of the DNN 421 | :param depth: depth of the DNN 422 | :param device: which GPU to use (for machines with multiple GPUs, this avoid taking up all GPUs) 423 | :param noise: standard variation of noise of the tested images 424 | :return: 425 | """ 426 | os.environ['CUDA_VISIBLE_DEVICES'] = device 427 | estimator = Estimator(batchSize=1, feature_dim=feature_dim, depth=depth) 428 | regexp = re.compile(r'.*\.(%s)' % '(jpg)|(png)|(bmp)|(tif)') 429 | inputFolder = 'data/real' 430 | 431 | psize = 500 432 | max_value = 255.0 433 | 434 | crop = 0 435 | n = 0 436 | 437 | avg_en = 0 438 | 439 | for d, dirs, files in os.walk(inputFolder): 440 | for f in files: 441 | if regexp.match(f): 442 | print('image', n, f) 443 | 444 | image = cv2.imread(os.path.join(d, f)) 445 | #image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) 446 | #cv2.imwrite('%s/%s_rgb.png' % ('output', f), image) 447 | if DEBUG: 448 | print ('image.shape : ', image.shape) 449 | 450 | if n == 0: 451 | xshape = [psize, psize, 3] 452 | yshape = [psize, psize, 3] 453 | estimator.load_model(modelPath, batchSize=1, xshape = xshape, yshape=yshape) 454 | 455 | #cv2.imwrite('%s/%s_in.bmp' % ('output', f), np.uint8(image / max_value * 255.0 + 0.5)) 456 | image = image / max_value 457 | 458 | 459 | # cv2.imwrite('%s/%s_in.png' % ('output', f), np.uint8(image * 255 + 0.5)) 460 | 461 | R, runtime = estimator.denoise_bayer(image, psize, crop) 462 | # out = np.uint8(R * 255 + 0.5) 463 | 464 | estimated_noise = np.mean(np.mean(np.mean(R, axis=0), axis=0), axis=0) 465 | 466 | if DEBUG: 467 | print('max value = ', np.max(np.abs(R))) 468 | print('time : ', runtime, ' ms') 469 | 470 | #cv2.imwrite('data/ne_res.png', out) 471 | with h5py.File('data/ne_res.h5', "w") as outFile: 472 | outFile.create_dataset('out', data=R * 255, compression='gzip') 473 | 474 | print('estimate_noise : ', estimated_noise * 255.0) 475 | # cv2.imwrite('%s/%s.png' % ('output', f), out) 476 | with open('data/time.txt', 'w') as out_file: 477 | print(runtime, file=out_file) 478 | n += 1 479 | avg_en += estimated_noise 480 | 481 | print('avg_en : ', avg_en / n * 255.0) 482 | estimator.sess.close() 483 | 484 | def test(modelPath, feature_dim, depth, device, noise, use_scalar_noise=True): 485 | """ 486 | Denoise noisy images using Denoiser class with pre-trained model. 487 | :param modelPath: path to save trained model 488 | :param feature_dim: width of the DNN 489 | :param depth: depth of the DNN 490 | :param device: which GPU to use (for machines with multiple GPUs, this avoid taking up all GPUs) 491 | :param noise: standard variation of noise of the tested images 492 | :return: 493 | """ 494 | os.environ['CUDA_VISIBLE_DEVICES'] = device 495 | denoiser = Denoiser(batchSize=1, feature_dim=feature_dim, depth=depth, use_scalar_noise=use_scalar_noise) 496 | regexp = re.compile(r'.*\.(%s)' % '(jpg)|(png)') 497 | inputFolder = 'data' 498 | 499 | psize = 500 500 | noise_level = noise / 255.0 501 | 502 | print('noise_level: ', noise_level) 503 | max_value = 255.0 504 | 505 | crop = 0 506 | n = 0 507 | 508 | dc = DatabaseCreator() 509 | 510 | for d, dirs, files in os.walk(inputFolder): 511 | for f in files: 512 | if regexp.match(f): 513 | print('image', n, f) 514 | 515 | image = cv2.imread(os.path.join(d, f)) 516 | #image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) 517 | cv2.imwrite('%s/%s_rgb.png' % ('output', f), image) 518 | 519 | image = image + np.random.randn(image.shape[0], image.shape[1], image.shape[2]) * noise 520 | image = dc.rgb2bayer3d(image) 521 | 522 | if DEBUG: 523 | print ('image.shape : ', image.shape) 524 | 525 | if n == 0: 526 | xshape = [psize, psize, 3] 527 | yshape = [psize, psize, 3] 528 | denoiser.load_model(modelPath, batchSize=1, xshape = xshape, yshape=yshape) 529 | 530 | #cv2.imwrite('%s/%s_in.bmp' % ('output', f), np.uint8(image / max_value * 255.0 + 0.5)) 531 | image = image / max_value 532 | 533 | 534 | cv2.imwrite('%s/%s_in.png' % ('output', f), np.uint8(image * 255 + 0.5)) 535 | 536 | R, runtime = denoiser.denoise_bayer(image, noise_level, psize, crop) 537 | out = np.uint8(R * 255 + 0.5) 538 | 539 | #print('out.shape = ', out.shape) 540 | 541 | if DEBUG: 542 | print('max value = ', np.max(np.abs(R))) 543 | print('time : ', runtime, ' ms') 544 | 545 | #cv2.imwrite('data/dnn_res.bmp', out) 546 | cv2.imwrite('%s/%s.png' % ('output', f), out) 547 | with open('data/time.txt', 'w') as out_file: 548 | print(runtime, file=out_file) 549 | n += 1 550 | denoiser.sess.close() 551 | 552 | 553 | if __name__ == '__main__': 554 | ## configuration 555 | bTrain = False 556 | modelPath = 'ne_w64d16_v2_sigma0_30' 557 | width = 64 558 | depth = 16 - 4 559 | device = '0' 560 | minNoiseLevel = 0.0 / 255.0 561 | maxNoiseLevel = 30.0 / 255.0 562 | #### end configuration 563 | 564 | if bTrain: 565 | train('models/%s' % modelPath, 'data/pristine_rgb2gray.h5', 566 | 'data/kodak_rgb2gray.h5', width, depth, minNoiseLevel, maxNoiseLevel, device=device, x_shape=[128, 128, 3], 567 | y_shape=[128, 128, 3]) 568 | else: 569 | parser = argparse.ArgumentParser() 570 | parser.add_argument('--noise', type=float, default=0.0, 571 | help='standard deviation of additive Gaussian noise, w.r.t to a [0,1] intensity scale.') 572 | args = parser.parse_args() 573 | 574 | noise = 5 575 | 576 | test('models/%s' % modelPath, width, depth=depth, device=device, noise=noise) 577 | #test_real('models/%s' % modelPath, width, depth=depth, device=device) 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | -------------------------------------------------------------------------------- /models/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/models/.DS_Store -------------------------------------------------------------------------------- /models/dn_sigma0_50/deep_isp.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/models/dn_sigma0_50/deep_isp.pickle -------------------------------------------------------------------------------- /models/dn_sigma0_50/loss.txt: -------------------------------------------------------------------------------- 1 | 0 5 0.0887626 0.0202255 2 | 1 5 0.0137187 0.0141125 3 | 2 5 0.00547461 0.00605746 4 | 3 5 0.00317966 0.0050944 5 | 4 5 0.0022888 0.00438851 6 | 5 5 0.0017972 0.00364419 7 | 6 5 0.00170691 0.00339342 8 | 7 5 0.00164649 0.00307221 9 | 8 5 0.00147041 0.00280626 10 | 9 5 0.00143476 0.00265514 11 | 10 5 0.00150127 0.00247777 12 | 11 5 0.00139211 0.00230633 13 | 12 5 0.00125221 0.00211746 14 | 13 5 0.00137195 0.00209728 15 | 14 5 0.00133482 0.00191281 16 | 15 5 0.00123559 0.00187912 17 | 16 5 0.00121959 0.00227408 18 | 17 5 0.00151127 0.00179878 19 | 18 5 0.0011601 0.001606 20 | 19 5 0.00115925 0.00156046 21 | 20 5 0.00113322 0.00152516 22 | 21 5 0.00121194 0.00159557 23 | 22 5 0.00114943 0.0014212 24 | 23 5 0.00105 0.00134557 25 | 24 5 0.000990649 0.00134174 26 | 25 5 0.00147417 0.00149865 27 | 26 5 0.00110651 0.00129518 28 | 27 5 0.00106523 0.00124249 29 | 28 5 0.00103895 0.00117937 30 | 29 5 0.00102958 0.00117921 31 | 30 5 0.00104866 0.00116296 32 | 31 5 0.00100028 0.00113945 33 | 32 5 0.00102193 0.00111816 34 | 33 5 0.00114779 0.00125689 35 | 34 5 0.00102883 0.00107139 36 | 35 5 0.00101302 0.0010304 37 | 36 5 0.00104806 0.00104497 38 | 37 5 0.00104071 0.00113454 39 | 38 5 0.000961051 0.000959828 40 | 39 5 0.00102225 0.00098013 41 | 40 5 0.00104154 0.00090752 42 | 41 5 0.00112127 0.00098723 43 | 42 5 0.00100484 0.000897872 44 | 43 5 0.00110323 0.00105708 45 | 44 5 0.00108724 0.00086606 46 | 45 5 0.000932886 0.00094813 47 | 46 5 0.00125561 0.000892508 48 | 47 5 0.000935912 0.000810898 49 | 48 5 0.000872547 0.000844479 50 | 49 5 0.000978768 0.000994823 51 | 50 5 0.00101867 0.000792831 52 | 51 5 0.000936376 0.000755373 53 | 52 5 0.000799159 0.000725277 54 | 53 5 0.000874936 0.00071745 55 | 54 5 0.000870966 0.000691024 56 | 55 5 0.000991074 0.000692203 57 | 56 5 0.000950598 0.00130661 58 | 57 5 0.00108069 0.000684931 59 | 58 5 0.000896593 0.000687413 60 | 59 5 0.000906321 0.000650345 61 | 60 5 0.000906838 0.00068267 62 | 61 5 0.000902696 0.00063135 63 | 62 5 0.0008186 0.000878456 64 | 63 5 0.000993153 0.000724203 65 | 64 5 0.00097093 0.000604358 66 | 65 5 0.000897648 0.000632076 67 | 66 5 0.00113419 0.00063752 68 | 67 5 0.000918972 0.000601918 69 | 68 5 0.000904137 0.000569361 70 | 69 5 0.000792708 0.000553155 71 | 70 5 0.000809093 0.000590592 72 | 71 5 0.000901025 0.0005598 73 | 72 5 0.000828276 0.000525916 74 | 73 5 0.000813173 0.000541551 75 | 74 5 0.000903174 0.000555015 76 | 75 5 0.000975073 0.000608145 77 | 76 5 0.000923961 0.000539902 78 | 77 5 0.000798052 0.000542914 79 | 78 5 0.000742671 0.000493376 80 | 79 5 0.000909854 0.000501173 81 | 80 5 0.00090225 0.000497535 82 | 81 5 0.00108612 0.000978769 83 | 82 5 0.000943923 0.000516528 84 | 83 5 0.000950604 0.000509223 85 | 84 5 0.000866508 0.000497893 86 | 85 5 0.000802862 0.000479543 87 | 86 5 0.000770692 0.000613545 88 | 87 5 0.00105138 0.000512322 89 | 88 5 0.000834513 0.000489033 90 | 89 5 0.000815313 0.000471651 91 | 90 5 0.000797048 0.000476303 92 | 91 5 0.000896133 0.000717707 93 | 92 5 0.000805208 0.000471171 94 | 93 5 0.000764717 0.000481353 95 | 94 5 0.000846839 0.000453507 96 | 95 5 0.000757312 0.000498604 97 | 96 5 0.00076185 0.00044579 98 | 97 5 0.000831529 0.000497174 99 | 98 5 0.000879678 0.000512888 100 | 99 5 0.00102277 0.000511387 101 | 100 5 0.000790303 0.000450336 102 | 101 5 0.000770017 0.000447479 103 | 102 5 0.000768636 0.000443305 104 | 103 5 0.000805527 0.000428113 105 | 104 5 0.000730888 0.00043238 106 | 105 5 0.000799438 0.000452654 107 | 106 5 0.000747355 0.000456997 108 | 107 5 0.000785193 0.000417537 109 | 108 5 0.000830245 0.000546378 110 | 109 5 0.000775584 0.000531206 111 | 110 5 0.000935907 0.00048689 112 | 111 5 0.000853386 0.000420305 113 | 112 5 0.000777475 0.000455442 114 | 113 5 0.000770601 0.00042041 115 | 114 5 0.00072463 0.000415605 116 | 115 5 0.000899048 0.000478346 117 | 116 5 0.000882202 0.000480322 118 | 117 5 0.000778238 0.000416374 119 | 118 5 0.000710147 0.000422553 120 | 119 5 0.000864896 0.000434324 121 | 120 5 0.000807781 0.000414686 122 | 121 5 0.000736346 0.000411717 123 | 122 5 0.000776144 0.000426743 124 | 123 5 0.00106931 0.000902962 125 | 124 5 0.000810408 0.000429422 126 | 125 5 0.00074159 0.000398147 127 | 126 5 0.000733796 0.000409181 128 | 127 5 0.000766631 0.000388106 129 | 128 5 0.000811112 0.000402415 130 | 129 5 0.000736168 0.00042613 131 | 130 5 0.000790828 0.000415498 132 | 131 5 0.000740077 0.000503113 133 | 132 5 0.000712297 0.00038901 134 | 133 5 0.000771056 0.000412962 135 | 134 5 0.000732474 0.000398087 136 | 135 5 0.000829318 0.000430771 137 | 136 5 0.000833101 0.000426593 138 | 137 5 0.000831979 0.000386979 139 | 138 5 0.000680852 0.000377836 140 | 139 5 0.000762411 0.000384192 141 | 140 5 0.000846307 0.000437873 142 | 141 5 0.000735563 0.000408594 143 | 142 5 0.000754886 0.00038884 144 | 143 5 0.000707174 0.000394519 145 | 144 5 0.000953519 0.000418261 146 | 145 5 0.000758313 0.000379855 147 | 146 5 0.000706719 0.000387093 148 | 147 5 0.000706072 0.000394667 149 | 148 5 0.000683986 0.000364888 150 | 149 5 0.000752633 0.000373321 151 | 150 5 0.000681079 0.000359016 152 | 151 5 0.000877706 0.000486464 153 | 152 5 0.000932573 0.000400311 154 | 153 5 0.000725174 0.000359867 155 | 154 5 0.000718881 0.000366041 156 | 155 5 0.000752248 0.000355749 157 | 156 5 0.000817314 0.000422956 158 | 157 5 0.000742001 0.000362198 159 | 158 5 0.000760941 0.00036002 160 | 159 5 0.000722564 0.000358721 161 | 160 5 0.000738501 0.000398872 162 | 161 5 0.000723128 0.000350189 163 | 162 5 0.0007851 0.000378552 164 | 163 5 0.000800579 0.000365513 165 | 164 5 0.000762847 0.000351482 166 | 165 5 0.000708836 0.000351096 167 | 166 5 0.00071681 0.000342281 168 | 167 5 0.000651631 0.000347309 169 | 168 5 0.000738964 0.000355807 170 | 169 5 0.000780642 0.000408923 171 | 170 5 0.00075044 0.000369075 172 | 171 5 0.000771684 0.000359715 173 | 172 5 0.000719267 0.000354656 174 | 173 5 0.000783884 0.000406308 175 | 174 5 0.000769559 0.000354542 176 | 175 5 0.000699846 0.000340282 177 | 176 5 0.000774672 0.000385003 178 | 177 5 0.000729763 0.000340526 179 | 178 5 0.000690666 0.000339881 180 | 179 5 0.000683959 0.000340456 181 | 180 5 0.000712744 0.000406273 182 | 181 5 0.000714551 0.000372399 183 | 182 5 0.000753498 0.000329691 184 | 183 5 0.000740116 0.000360655 185 | 184 5 0.000698356 0.000349437 186 | 185 5 0.000678377 0.000335687 187 | 186 5 0.000673724 0.000345773 188 | 187 5 0.000903891 0.000532662 189 | 188 5 0.000797964 0.00036176 190 | 189 5 0.000743393 0.000350445 191 | 190 5 0.000729007 0.00035667 192 | 191 5 0.000744503 0.000334562 193 | 192 5 0.00072404 0.000341873 194 | 193 5 0.000700757 0.000340412 195 | 194 5 0.000726961 0.000350806 196 | 195 5 0.000705493 0.00035896 197 | 196 5 0.000680255 0.000369982 198 | 197 5 0.000742618 0.000364084 199 | 198 5 0.000718113 0.000349585 200 | 199 5 0.00072783 0.000410351 201 | 200 5 0.000639615 0.000357969 202 | 201 5 0.000821157 0.000334002 203 | 202 5 0.000745822 0.000324161 204 | 203 5 0.000704426 0.000320571 205 | 204 5 0.000761926 0.000325005 206 | 205 5 0.000636054 0.000361915 207 | 206 5 0.000735726 0.000343002 208 | 207 5 0.000702001 0.000396962 209 | 208 5 0.00107771 0.000844961 210 | 209 5 0.000731756 0.000349092 211 | 210 5 0.000708989 0.000322874 212 | 211 5 0.000693619 0.000314816 213 | 212 5 0.000734657 0.000314543 214 | 213 5 0.000751097 0.000314319 215 | 214 5 0.000810651 0.000317619 216 | 215 5 0.000732235 0.000317127 217 | 216 5 0.000819924 0.000342263 218 | 217 5 0.000738818 0.000327488 219 | 218 5 0.000682056 0.000312983 220 | 219 5 0.000741951 0.000374839 221 | 220 5 0.000732368 0.00032394 222 | 221 5 0.000722713 0.000311207 223 | 222 5 0.000719202 0.000314171 224 | 223 5 0.000695529 0.000358659 225 | 224 5 0.000688835 0.000316172 226 | 225 5 0.000713092 0.000306725 227 | 226 5 0.000702082 0.000353134 228 | 227 5 0.00076313 0.000311084 229 | 228 5 0.000674815 0.000304344 230 | 229 5 0.000654565 0.000335647 231 | 230 5 0.000644938 0.000343175 232 | 231 5 0.000723514 0.000325432 233 | 232 5 0.000751072 0.00034178 234 | 233 5 0.000667491 0.00031976 235 | 234 5 0.000643295 0.000391059 236 | 235 5 0.000725334 0.000483135 237 | 236 5 0.000695241 0.000325681 238 | 237 5 0.000691766 0.000310243 239 | 238 5 0.000665127 0.000301087 240 | 239 5 0.000727004 0.000313109 241 | 240 5 0.000726865 0.000324068 242 | 241 5 0.000703933 0.000315647 243 | 242 5 0.000659642 0.000334096 244 | 243 5 0.000730477 0.000330915 245 | 244 5 0.000731585 0.000330181 246 | 245 5 0.000741897 0.000316791 247 | 246 5 0.000587268 0.000361132 248 | 247 5 0.000714286 0.000298607 249 | 248 5 0.000674949 0.000295143 250 | 249 5 0.000748102 0.000403902 251 | 250 5 0.000704454 0.00031935 252 | 251 5 0.00059349 0.000287139 253 | 252 5 0.00067087 0.000302364 254 | 253 5 0.000662097 0.000321749 255 | 254 5 0.000674756 0.000313524 256 | 255 5 0.000660193 0.000283334 257 | 256 5 0.000682621 0.000316314 258 | 257 5 0.000710503 0.000295957 259 | 258 5 0.000710687 0.000296202 260 | 259 5 0.000661187 0.000291494 261 | 260 5 0.000716528 0.000322125 262 | 261 5 0.000749409 0.000336728 263 | 262 5 0.000618673 0.000288549 264 | 263 5 0.000676425 0.000299 265 | 264 5 0.000666625 0.000290584 266 | 265 5 0.000662249 0.000284019 267 | 266 5 0.000676782 0.000303889 268 | 267 5 0.000619931 0.000283867 269 | 268 5 0.000721313 0.000297178 270 | 269 5 0.000756631 0.000513339 271 | 270 5 0.000735105 0.000335251 272 | 271 5 0.000629838 0.000283615 273 | 272 5 0.000711864 0.00027977 274 | 273 5 0.000768739 0.000299616 275 | 274 5 0.00069359 0.000293501 276 | 275 5 0.000698048 0.000294731 277 | 276 5 0.000721649 0.000287695 278 | 277 5 0.00071133 0.000278603 279 | 278 5 0.000722139 0.000280893 280 | 279 5 0.000596849 0.00027646 281 | 280 5 0.000590284 0.000308851 282 | 281 5 0.000719265 0.000303594 283 | 282 5 0.000651048 0.000294684 284 | 283 5 0.000711941 0.00027783 285 | 284 5 0.000690806 0.000458288 286 | 285 5 0.000723861 0.000309342 287 | 286 5 0.000667364 0.000360126 288 | 287 5 0.000673417 0.000299503 289 | 288 5 0.000745675 0.000290157 290 | 289 5 0.00068537 0.000282802 291 | 290 5 0.000603791 0.000273406 292 | 291 5 0.000702852 0.000304734 293 | 292 5 0.000698028 0.000350638 294 | 293 5 0.000725104 0.00030424 295 | 294 5 0.000708945 0.000270819 296 | 295 5 0.000617817 0.000283031 297 | 296 5 0.000621487 0.000291868 298 | 297 5 0.000662876 0.000268999 299 | 298 5 0.000749826 0.000367877 300 | 299 5 0.000704011 0.000283793 301 | 300 5 0.000684115 0.0003002 302 | 301 5 0.00072465 0.00040251 303 | 302 5 0.000747327 0.000270424 304 | 303 5 0.000687794 0.000293553 305 | 304 5 0.000727584 0.000266629 306 | 305 5 0.000611812 0.000300104 307 | 306 5 0.000661125 0.000273994 308 | 307 5 0.000642563 0.000328172 309 | 308 5 0.000683366 0.000267036 310 | 309 5 0.000699822 0.000264647 311 | 310 5 0.000728271 0.000287469 312 | 311 5 0.000608447 0.000287507 313 | 312 5 0.000727764 0.000273041 314 | 313 5 0.000689009 0.00031924 315 | 314 5 0.000697794 0.000289527 316 | 315 5 0.000691007 0.000274788 317 | 316 5 0.000620433 0.000267072 318 | 317 5 0.00066615 0.000267002 319 | 318 5 0.00073965 0.000293884 320 | 319 5 0.000590897 0.000266294 321 | 320 5 0.000622855 0.000265388 322 | 321 5 0.000674133 0.000339306 323 | 322 5 0.000726442 0.000296621 324 | 323 5 0.000592099 0.000279865 325 | 324 5 0.0006804 0.000267244 326 | 325 5 0.000608046 0.000309099 327 | 326 5 0.000690921 0.000282077 328 | 327 5 0.000621547 0.000265284 329 | 328 5 0.000680401 0.000260587 330 | 329 5 0.000694039 0.000266301 331 | 330 5 0.000702351 0.000268029 332 | 331 5 0.000723937 0.00026731 333 | 332 5 0.000653644 0.000318363 334 | 333 5 0.000728757 0.000556511 335 | 334 5 0.00066766 0.000268187 336 | 335 5 0.00077188 0.000295599 337 | 336 5 0.0006856 0.000261982 338 | 337 5 0.00070498 0.00027257 339 | 338 5 0.000683088 0.000263607 340 | 339 5 0.00072343 0.000301171 341 | 340 5 0.00074314 0.000275626 342 | 341 5 0.000697556 0.000256192 343 | 342 5 0.000701044 0.000322503 344 | 343 5 0.000707463 0.000277738 345 | 344 5 0.000695802 0.000285616 346 | 345 5 0.000734437 0.000264347 347 | 346 5 0.000735776 0.000583656 348 | 347 5 0.000754177 0.000261608 349 | 348 5 0.000658221 0.000271098 350 | 349 5 0.000695546 0.000322764 351 | 350 5 0.000741473 0.000308547 352 | 351 5 0.000624766 0.000251841 353 | 352 5 0.000707755 0.000264369 354 | 353 5 0.000655894 0.000262331 355 | 354 5 0.000705584 0.000268304 356 | 355 5 0.000677602 0.000266601 357 | 356 5 0.000712369 0.000248124 358 | 357 5 0.000705779 0.000307899 359 | 358 5 0.000674715 0.000309659 360 | 359 5 0.000748658 0.000257399 361 | 360 5 0.000683753 0.000284325 362 | 361 5 0.000663144 0.000261123 363 | 362 5 0.00069604 0.000257099 364 | 363 5 0.000683483 0.000294914 365 | 364 5 0.000726133 0.000248457 366 | 365 5 0.000644027 0.000337241 367 | 366 5 0.000750226 0.000252351 368 | 367 5 0.000670155 0.000245118 369 | 368 5 0.000712777 0.000246425 370 | 369 5 0.000702897 0.00024295 371 | 370 5 0.000662248 0.00024994 372 | 371 5 0.000769994 0.000253326 373 | 372 5 0.000724568 0.000251491 374 | 373 5 0.000685474 0.000248346 375 | 374 5 0.000655419 0.000253147 376 | 375 5 0.000698451 0.000253915 377 | 376 5 0.000704534 0.000278544 378 | 377 5 0.00070564 0.000250655 379 | 378 5 0.000648187 0.000262296 380 | 379 5 0.000667202 0.000247164 381 | 380 5 0.000645257 0.000295619 382 | 381 5 0.00071812 0.000248477 383 | 382 5 0.000680841 0.000366367 384 | 383 5 0.000661077 0.000248871 385 | 384 5 0.000623623 0.000229889 386 | 385 5 0.000607159 0.000246776 387 | 386 5 0.000756549 0.000253957 388 | 387 5 0.000675284 0.000260262 389 | 388 5 0.000696593 0.000241605 390 | 389 5 0.000662184 0.000249047 391 | 390 5 0.000677612 0.000227692 392 | 391 5 0.000657457 0.000233498 393 | 392 5 0.000681126 0.000276747 394 | 393 5 0.000660957 0.000292328 395 | 394 5 0.000651176 0.000243811 396 | 395 5 0.0007086 0.000239912 397 | 396 5 0.000682977 0.000233745 398 | 397 5 0.000654637 0.000250175 399 | 398 5 0.000695935 0.000242902 400 | 399 5 0.00068794 0.000234123 401 | 400 5 0.000739232 0.000248093 402 | 401 5 0.000639671 0.00022978 403 | 402 5 0.000706152 0.000237558 404 | 403 5 0.000671846 0.000234466 405 | 404 5 0.000647748 0.000236448 406 | 405 5 0.000700384 0.00022998 407 | 406 5 0.000707432 0.000237447 408 | 407 5 0.000671879 0.00025375 409 | 408 5 0.00068214 0.000292021 410 | 409 5 0.000663813 0.000251098 411 | 410 5 0.000704293 0.000265559 412 | 411 5 0.000631389 0.000228354 413 | 412 5 0.000691695 0.000264864 414 | 413 5 0.000678845 0.000233926 415 | 414 5 0.000643817 0.000226205 416 | 415 5 0.000717161 0.000293749 417 | 416 5 0.000721355 0.000223381 418 | 417 5 0.000701697 0.000687951 419 | 418 5 0.000746189 0.00023848 420 | 419 5 0.000666731 0.000224008 421 | 420 5 0.000663131 0.000226891 422 | 421 5 0.00065437 0.000231601 423 | 422 5 0.00074263 0.000234317 424 | 423 5 0.000647778 0.000272087 425 | 424 5 0.000724589 0.000248525 426 | 425 5 0.000671517 0.000223474 427 | 426 5 0.000666547 0.000225955 428 | 427 5 0.000649868 0.000226496 429 | 428 5 0.000672009 0.000231783 430 | 429 5 0.000719121 0.000230218 431 | 430 5 0.00063995 0.000217786 432 | 431 5 0.000654217 0.000239239 433 | 432 5 0.000829566 0.000233747 434 | 433 5 0.000697133 0.000246233 435 | 434 5 0.000653836 0.000216768 436 | 435 5 0.00064706 0.000227363 437 | 436 5 0.000654375 0.000260757 438 | 437 5 0.000737231 0.00023909 439 | 438 5 0.00063836 0.000236785 440 | 439 5 0.000664212 0.000216872 441 | 440 5 0.000677231 0.000230885 442 | 441 5 0.00072002 0.000255943 443 | 442 5 0.000679289 0.00022748 444 | 443 5 0.000676153 0.000228032 445 | 444 5 0.000708161 0.000272395 446 | 445 5 0.000633075 0.00024328 447 | 446 5 0.000662241 0.0002179 448 | 447 5 0.00064172 0.000224994 449 | 448 5 0.00062463 0.00025496 450 | 449 5 0.000746176 0.000228335 451 | 450 5 0.000676399 0.000223033 452 | 451 5 0.000603428 0.000247684 453 | 452 5 0.000630305 0.000216103 454 | 453 5 0.000688012 0.000229992 455 | 454 5 0.000685284 0.000216505 456 | 455 5 0.000669359 0.000237145 457 | 456 5 0.000627841 0.000238467 458 | 457 5 0.000712122 0.000322946 459 | 458 5 0.000677329 0.000218541 460 | 459 5 0.000650591 0.000219372 461 | 460 5 0.000657156 0.000348784 462 | 461 5 0.000678763 0.000225344 463 | 462 5 0.000632703 0.000216922 464 | 463 5 0.000678828 0.000253671 465 | 464 5 0.000630802 0.000255441 466 | 465 5 0.000630089 0.000229708 467 | 466 5 0.000687986 0.000219968 468 | 467 5 0.000629754 0.000218695 469 | 468 5 0.000646503 0.000206133 470 | 469 5 0.000706176 0.000255681 471 | 470 5 0.000678797 0.000240549 472 | 471 5 0.000682953 0.000220147 473 | 472 5 0.000646756 0.000219224 474 | 473 5 0.000689303 0.000245299 475 | 474 5 0.000708875 0.000218367 476 | 475 5 0.000628309 0.000208113 477 | 476 5 0.000670534 0.000209591 478 | 477 5 0.000641437 0.000382207 479 | 478 5 0.000772705 0.000222476 480 | 479 5 0.000611984 0.000210744 481 | 480 5 0.000665316 0.000227632 482 | 481 5 0.000661131 0.000220473 483 | 482 5 0.000653771 0.000220015 484 | 483 5 0.000611164 0.000206037 485 | 484 5 0.000664202 0.000354846 486 | 485 5 0.000687076 0.000321938 487 | 486 5 0.000695923 0.000227259 488 | 487 5 0.000647122 0.00021763 489 | 488 5 0.000699097 0.000228161 490 | 489 5 0.000656812 0.000211354 491 | 490 5 0.000659652 0.000207919 492 | 491 5 0.000659865 0.000207124 493 | 492 5 0.000671244 0.000207751 494 | 493 5 0.000642161 0.00035733 495 | 494 5 0.000625534 0.000212225 496 | 495 5 0.000646122 0.000211678 497 | 496 5 0.000624451 0.000251054 498 | 497 5 0.000608052 0.000211914 499 | 498 5 0.000638336 0.000206462 500 | 499 5 0.000659257 0.000256981 501 | 500 5 0.000687092 0.000212328 502 | 501 5 0.00068467 0.000204943 503 | 502 5 0.000645916 0.000210125 504 | 503 5 0.000653412 0.000224967 505 | 504 5 0.000657361 0.000213364 506 | 505 5 0.000653423 0.000204548 507 | 506 5 0.000669715 0.000214435 508 | 507 5 0.00065183 0.000227577 509 | 508 5 0.000641793 0.000218977 510 | 509 5 0.000690482 0.000226823 511 | 510 5 0.000625808 0.000203416 512 | 511 5 0.00066968 0.000198351 513 | 512 5 0.000626491 0.000205107 514 | 513 5 0.000619153 0.000211052 515 | 514 5 0.000691468 0.000200989 516 | 515 5 0.000681387 0.000202425 517 | 516 5 0.00061201 0.000210646 518 | 517 5 0.000702516 0.000206097 519 | 518 5 0.000604116 0.000223317 520 | 519 5 0.000607221 0.000202156 521 | 520 5 0.000625823 0.00024687 522 | 521 5 0.00069322 0.000208553 523 | 522 5 0.00067801 0.000201758 524 | 523 5 0.000693125 0.000208626 525 | 524 5 0.000658677 0.000209348 526 | 525 5 0.000604163 0.000209578 527 | 526 5 0.000631325 0.000203881 528 | 527 5 0.000644107 0.000224895 529 | 528 5 0.000686546 0.000207474 530 | 529 5 0.000669628 0.000292564 531 | 530 5 0.000683563 0.000220248 532 | 531 5 0.000623321 0.000221066 533 | 532 5 0.000674175 0.000208136 534 | 533 5 0.000635685 0.000198848 535 | 534 5 0.000647448 0.00019572 536 | 535 5 0.000709226 0.000214066 537 | 536 5 0.000623819 0.000193076 538 | 537 5 0.000660303 0.000198049 539 | 538 5 0.000642352 0.000225179 540 | 539 5 0.000644418 0.000194059 541 | 540 5 0.000694778 0.000237318 542 | 541 5 0.000660119 0.000294147 543 | 542 5 0.000648924 0.000209481 544 | 543 5 0.000714531 0.000235365 545 | 544 5 0.00063613 0.000202905 546 | 545 5 0.000593476 0.000198247 547 | 546 5 0.000638934 0.000201687 548 | 547 5 0.000683475 0.000195418 549 | 548 5 0.000634424 0.000209525 550 | 549 5 0.000620048 0.000206364 551 | 550 5 0.000683359 0.000209995 552 | 551 5 0.000641817 0.000226358 553 | 552 5 0.000601209 0.000204053 554 | 553 5 0.000647339 0.000201064 555 | 554 5 0.000640673 0.000199436 556 | 555 5 0.000662348 0.000197781 557 | 556 5 0.000632055 0.000219613 558 | 557 5 0.000667307 0.00019703 559 | 558 5 0.000666697 0.000196714 560 | 559 5 0.000681161 0.000208277 561 | 560 5 0.000600839 0.00019912 562 | 561 5 0.000613854 0.000197531 563 | 562 5 0.000630496 0.00019985 564 | 563 5 0.000688107 0.000206011 565 | 564 5 0.000635454 0.000226483 566 | 565 5 0.000639512 0.000193533 567 | 566 5 0.000580161 0.00019625 568 | 567 5 0.000677763 0.000202302 569 | 568 5 0.000658862 0.000244039 570 | 569 5 0.000702285 0.00021344 571 | 570 5 0.000633348 0.000193408 572 | 571 5 0.000639721 0.000226398 573 | 572 5 0.000610274 0.000191375 574 | 573 5 0.000611132 0.000209564 575 | 574 5 0.000659041 0.000194973 576 | 575 5 0.000652597 0.00019395 577 | 576 5 0.000648507 0.000210573 578 | 577 5 0.000614568 0.000198661 579 | 578 5 0.000618892 0.000204052 580 | 579 5 0.000678305 0.000192019 581 | 580 5 0.000625016 0.000210612 582 | 581 5 0.000650359 0.000196133 583 | 582 5 0.000653107 0.000201027 584 | 583 5 0.000680666 0.000201653 585 | 584 5 0.000602091 0.000192894 586 | 585 5 0.000641566 0.00023043 587 | 586 5 0.000721979 0.000213667 588 | 587 5 0.000624352 0.000195642 589 | 588 5 0.000655671 0.000199048 590 | 589 5 0.000661934 0.000191279 591 | 590 5 0.000658326 0.000211158 592 | 591 5 0.000676917 0.00020385 593 | 592 5 0.000638409 0.000278101 594 | 593 5 0.000666965 0.000194365 595 | 594 5 0.000599255 0.000225835 596 | 595 5 0.000608085 0.000191418 597 | 596 5 0.000641512 0.000194998 598 | 597 5 0.000595241 0.000195474 599 | 598 5 0.000655849 0.000192091 600 | 599 5 0.000589148 0.000199846 601 | 600 5 0.000623042 0.000215901 602 | 601 5 0.000620938 0.000208561 603 | 602 5 0.000624624 0.000210542 604 | 603 5 0.000656343 0.000191835 605 | 604 5 0.000615539 0.000199823 606 | 605 5 0.000636194 0.000240783 607 | 606 5 0.000581409 0.000189694 608 | 607 5 0.000586387 0.000224161 609 | 608 5 0.000678106 0.000190976 610 | 609 5 0.000707783 0.000203879 611 | 610 5 0.000591454 0.000190368 612 | 611 5 0.000632194 0.000208327 613 | 612 5 0.000603182 0.00019066 614 | 613 5 0.000591652 0.00024634 615 | 614 5 0.000650567 0.000188501 616 | 615 5 0.000666205 0.000190727 617 | 616 5 0.00064096 0.000189684 618 | 617 5 0.000681176 0.000238735 619 | 618 5 0.00066895 0.000193253 620 | 619 5 0.000657781 0.000194453 621 | 620 5 0.000611286 0.000184251 622 | 621 5 0.000650198 0.000189745 623 | 622 5 0.00063866 0.000289772 624 | 623 5 0.000678987 0.000189585 625 | 624 5 0.000617453 0.000216831 626 | 625 5 0.000665735 0.000189459 627 | 626 5 0.000613946 0.000188232 628 | 627 5 0.000628441 0.000201424 629 | 628 5 0.000649473 0.000201141 630 | 629 5 0.000712753 0.000197059 631 | 630 5 0.000579879 0.000185799 632 | 631 5 0.000638542 0.000186096 633 | 632 5 0.000645066 0.000189656 634 | 633 5 0.000647029 0.000205334 635 | 634 5 0.00070897 0.000203032 636 | 635 5 0.000663331 0.000185563 637 | 636 5 0.000630905 0.00019377 638 | 637 5 0.000653135 0.000186696 639 | 638 5 0.000671869 0.000186217 640 | 639 5 0.000669539 0.000186619 641 | 640 5 0.000636556 0.000194543 642 | 641 5 0.00065115 0.000200637 643 | 642 5 0.000640792 0.000186789 644 | 643 5 0.000634543 0.000202534 645 | 644 5 0.00062303 0.000195782 646 | 645 5 0.000616219 0.00019501 647 | 646 5 0.000585823 0.000194802 648 | 647 5 0.000618918 0.000183661 649 | 648 5 0.00067551 0.00021218 650 | 649 5 0.000700916 0.00021997 651 | 650 5 0.00064347 0.000194123 652 | 651 5 0.000653723 0.00018482 653 | 652 5 0.00064029 0.000231323 654 | 653 5 0.000634961 0.000183656 655 | 654 5 0.00062385 0.00018898 656 | 655 5 0.000674605 0.000195164 657 | 656 5 0.000682757 0.000201335 658 | 657 5 0.000659038 0.000184544 659 | 658 5 0.000660702 0.00018686 660 | 659 5 0.000683085 0.000192075 661 | 660 5 0.000652935 0.000186882 662 | 661 5 0.000692234 0.000184574 663 | 662 5 0.000630127 0.000201733 664 | 663 5 0.000610978 0.000194329 665 | 664 5 0.00063141 0.000213382 666 | 665 5 0.000632771 0.000182244 667 | 666 5 0.00067723 0.000187325 668 | 667 5 0.000654221 0.000190535 669 | 668 5 0.000616354 0.000190659 670 | 669 5 0.000588997 0.000220133 671 | 670 5 0.000665508 0.000187419 672 | 671 5 0.000685428 0.000282963 673 | 672 5 0.000608202 0.000192997 674 | 673 5 0.000640927 0.000181384 675 | 674 5 0.000641224 0.000184462 676 | 675 5 0.000674558 0.000197154 677 | 676 5 0.000624919 0.000198659 678 | 677 5 0.000631858 0.00019071 679 | 678 5 0.000617667 0.000190077 680 | 679 5 0.00060539 0.000203497 681 | 680 5 0.000679145 0.000189531 682 | 681 5 0.00058702 0.000182493 683 | 682 5 0.000663436 0.000214249 684 | 683 5 0.000601877 0.000187204 685 | 684 5 0.000620013 0.000215779 686 | 685 5 0.000622392 0.000185113 687 | 686 5 0.000656906 0.000252143 688 | 687 5 0.000682916 0.000190559 689 | 688 5 0.000652793 0.000188412 690 | 689 5 0.000612487 0.00019901 691 | 690 5 0.000626868 0.000196991 692 | 691 5 0.000711462 0.000185384 693 | 692 5 0.000630882 0.00018773 694 | 693 5 0.000603144 0.00019202 695 | 694 5 0.000681486 0.00019642 696 | 695 5 0.000624512 0.000215211 697 | 696 5 0.000633139 0.00020727 698 | 697 5 0.000615475 0.00022939 699 | 698 5 0.000715488 0.000196609 700 | 699 5 0.00060926 0.000196342 701 | 700 5 0.00060512 0.000180548 702 | 701 5 0.000656318 0.000182284 703 | 702 5 0.000615253 0.000186635 704 | 703 5 0.000602232 0.000186451 705 | 704 5 0.000638449 0.000196044 706 | 705 5 0.000629439 0.000180678 707 | 706 5 0.000623698 0.000212501 708 | 707 5 0.00064705 0.000180656 709 | 708 5 0.000655353 0.000207315 710 | 709 5 0.000576797 0.000179559 711 | 710 5 0.00063593 0.000192641 712 | 711 5 0.000652349 0.000194875 713 | 712 5 0.000609989 0.000182479 714 | 713 5 0.000683262 0.0001928 715 | 714 5 0.000633171 0.000206581 716 | 715 5 0.000643788 0.000217265 717 | 716 5 0.000671834 0.000186541 718 | 717 5 0.00058098 0.000197346 719 | 718 5 0.000645156 0.000194978 720 | 719 5 0.00066242 0.000196653 721 | 720 5 0.000655636 0.000180257 722 | 721 5 0.000659121 0.000184768 723 | 722 5 0.0006396682 0.00018704387 724 | 723 5 0.0006411779 0.00017869992 725 | 724 5 0.00065803586 0.00024861636 726 | 725 5 0.00065382966 0.00020816269 727 | 726 5 0.00064544316 0.00018383747 728 | 727 5 0.0005900631 0.00017699813 729 | 728 5 0.0007229085 0.00019205008 730 | 729 5 0.0006256249 0.00018880323 731 | 730 5 0.0006412805 0.00018299493 732 | 731 5 0.00059381913 0.00019098313 733 | 732 5 0.0006433932 0.00018836923 734 | 733 5 0.0006101074 0.00018488937 735 | 734 5 0.00062699994 0.00021293505 736 | 735 5 0.0006455262 0.00020581746 737 | 736 5 0.00066687004 0.00021249989 738 | 737 5 0.0006458421 0.00019408297 739 | 738 5 0.0006468061 0.00018880806 740 | 739 5 0.000659358 0.00017937551 741 | 740 5 0.00065343163 0.00019204679 742 | 741 5 0.00063548965 0.0001758437 743 | 742 5 0.0006552419 0.00019687624 744 | 743 5 0.0006530721 0.00019007809 745 | 744 5 0.00066499284 0.00018195449 746 | 745 5 0.0005936431 0.0001866918 747 | 746 5 0.00065219594 0.00017977877 748 | 747 5 0.0005895796 0.00018085417 749 | 748 5 0.00067555154 0.00019573227 750 | 749 5 0.000604327 0.00019355444 751 | 750 5 0.0006373932 0.00020641077 752 | 751 5 0.0006120566 0.00019444093 753 | 752 5 0.0006642633 0.0001818243 754 | 753 5 0.0006105088 0.00017744549 755 | 754 5 0.00060357165 0.00019255617 756 | 755 5 0.00065419596 0.0001816025 757 | 756 5 0.00061412697 0.00018047122 758 | 757 5 0.00065242517 0.00018998132 759 | 758 5 0.0006658331 0.00022307299 760 | 759 5 0.0006517445 0.00017760893 761 | 760 5 0.00064635486 0.00018494019 762 | 761 5 0.00065369677 0.00020192053 763 | 762 5 0.00062920776 0.00018293357 764 | 763 5 0.0006672746 0.00020596404 765 | 764 5 0.00064968434 0.00017527159 766 | 765 5 0.00059959333 0.00028358653 767 | 766 5 0.000616544 0.00019130483 768 | 767 5 0.00059857516 0.00017819663 769 | 768 5 0.0006886608 0.00018810485 770 | 769 5 0.0006207186 0.00027651043 771 | 770 5 0.0006388872 0.00018184318 772 | 771 5 0.0006367501 0.00017825192 773 | 772 5 0.0006333596 0.00018348802 774 | 773 5 0.0006151057 0.00017311337 775 | 774 5 0.0006571097 0.00022432774 776 | 775 5 0.0006595435 0.00020028606 777 | 776 5 0.0006461153 0.0001762415 778 | 777 5 0.0006377277 0.00018246629 779 | 778 5 0.0006293992 0.00017602734 780 | 779 5 0.0006644723 0.00017511427 781 | 780 5 0.000601779 0.00017410795 782 | 781 5 0.0006016012 0.00022403595 783 | 782 5 0.0006534267 0.00018269818 784 | 783 5 0.00063301396 0.0001779722 785 | 784 5 0.00064160046 0.00019155907 786 | 785 5 0.00063181814 0.00021281769 787 | 786 5 0.00063419883 0.0001800165 788 | 787 5 0.0006634902 0.00017669755 789 | 788 5 0.00064999884 0.00017570908 790 | 789 5 0.00063900516 0.00018545076 791 | 790 5 0.0006292089 0.00017236364 792 | 791 5 0.00061611447 0.00017426343 793 | 792 5 0.00060711504 0.00018384773 794 | 793 5 0.0006504014 0.00017915871 795 | 794 5 0.0005891474 0.0001871822 796 | 795 5 0.000652363 0.0001773741 797 | 796 5 0.0006212884 0.00018647901 798 | 797 5 0.0006440884 0.00019997952 799 | 798 5 0.00062032056 0.00017409737 800 | 799 5 0.00059101306 0.0002114519 801 | 800 5 0.000620724 0.00017283564 802 | 801 5 0.00062598125 0.00019386272 803 | 802 5 0.00060114695 0.00017460196 804 | 803 5 0.0006343853 0.00017292662 805 | 804 5 0.00061988266 0.00017348025 806 | 805 5 0.0006294295 0.00018154924 807 | 806 5 0.0006173438 0.00017361397 808 | 807 5 0.00065620104 0.00018831278 809 | 808 5 0.0006718482 0.00017938134 810 | 809 5 0.0006273132 0.00018073928 811 | 810 5 0.00065025914 0.00018335278 812 | 811 5 0.00063615036 0.00017458874 813 | 812 5 0.00062355073 0.00017329428 814 | 813 5 0.0006329602 0.00024289533 815 | 814 5 0.0006550983 0.00017640211 816 | 815 5 0.0006101812 0.00017771662 817 | 816 5 0.0006514588 0.00018064036 818 | 817 5 0.0006630907 0.000186285 819 | 818 5 0.000608149 0.00017973538 820 | 819 5 0.0005947289 0.00017610368 821 | 820 5 0.0005946675 0.00018318859 822 | 821 5 0.0006679962 0.00017238005 823 | 822 5 0.00064690236 0.00019022803 824 | 823 5 0.00059898663 0.0001859655 825 | 824 5 0.00062879384 0.00017492351 826 | 825 5 0.0006648715 0.00017746114 827 | 826 5 0.0006237222 0.00019413688 828 | 827 5 0.0006405284 0.00017933776 829 | 828 5 0.00060831814 0.00017350256 830 | 829 5 0.0006551253 0.00017607426 831 | 830 5 0.0006297416 0.0002049392 832 | 831 5 0.0006461685 0.0001856073 833 | 832 5 0.0006172077 0.00017122633 834 | 833 5 0.0006133446 0.00017960004 835 | 834 5 0.0006502804 0.00018513238 836 | 835 5 0.0005902171 0.00016887729 837 | 836 5 0.0006248602 0.00018272102 838 | 837 5 0.0006549349 0.00017503578 839 | 838 5 0.00058612524 0.00018941755 840 | 839 5 0.0006799138 0.00017834164 841 | 840 5 0.0006003608 0.00017046992 842 | 841 5 0.00062889664 0.00018103246 843 | 842 5 0.00061568315 0.00018698408 844 | 843 5 0.0005779959 0.00017412067 845 | 844 5 0.00062402675 0.00018107337 846 | 845 5 0.0006509819 0.00017193214 847 | 846 5 0.0006481452 0.00021176519 848 | 847 5 0.0006782559 0.00017367577 849 | 848 5 0.00064483704 0.0001750263 850 | 849 5 0.00063905475 0.00020734694 851 | 850 5 0.0006688676 0.00017670688 852 | 851 5 0.00060414406 0.00018317078 853 | 852 5 0.0006430322 0.00017006228 854 | 853 5 0.0006164777 0.00017555965 855 | 854 5 0.0006071686 0.00017203666 856 | 855 5 0.0005963446 0.00017102085 857 | 856 5 0.00063581904 0.0001729664 858 | 857 5 0.00058119866 0.0001778365 859 | 858 5 0.00060185534 0.00017024594 860 | 859 5 0.00062308495 0.0001769542 861 | 860 5 0.0006123811 0.00017442882 862 | 861 5 0.00062184234 0.0001690414 863 | 862 5 0.0006178547 0.00017328572 864 | 863 5 0.0006173042 0.00018235225 865 | 864 5 0.0006272475 0.00016695743 866 | 865 5 0.00059462484 0.00021748559 867 | 866 5 0.00066400203 0.00017173955 868 | 867 5 0.0006072221 0.0001707599 869 | 868 5 0.000591413 0.00018130486 870 | 869 5 0.0006150896 0.00020989204 871 | 870 5 0.0006247256 0.00017714205 872 | 871 5 0.0006015646 0.00017625478 873 | 872 5 0.0006510014 0.0001729977 874 | 873 5 0.00059993553 0.00017273687 875 | 874 5 0.0005886155 0.00018306648 876 | 875 5 0.00060503633 0.00017371168 877 | 876 5 0.0006669344 0.00017897329 878 | 877 5 0.0006428659 0.00017144147 879 | 878 5 0.00060599024 0.00019495585 880 | 879 5 0.00064374716 0.0001989256 881 | 880 5 0.000563973 0.00017488218 882 | 881 5 0.00064094365 0.00017292076 883 | 882 5 0.00061276637 0.00017920321 884 | 883 5 0.0006059559 0.00017614616 885 | 884 5 0.00064449484 0.00017049414 886 | 885 5 0.00064401 0.00017259113 887 | 886 5 0.0006117487 0.00017661422 888 | 887 5 0.0006130721 0.00017815502 889 | 888 5 0.0006806249 0.00017719646 890 | 889 5 0.00059023424 0.00017976646 891 | 890 5 0.0006199549 0.0002072917 892 | 891 5 0.00059779134 0.00018896237 893 | 892 5 0.0006340489 0.00017180131 894 | 893 5 0.0006189388 0.00017463986 895 | 894 5 0.0005811099 0.0001822393 896 | 895 5 0.00066176115 0.0001951719 897 | 896 5 0.0006138179 0.00017108214 898 | 897 5 0.00061277294 0.00017257738 899 | 898 5 0.0006002761 0.00016888794 900 | 899 5 0.0006182568 0.00017233806 901 | 900 5 0.0006186083 0.00016696755 902 | 901 5 0.0005922849 0.00018567331 903 | 902 5 0.0006058734 0.00017963351 904 | 903 5 0.0006123986 0.00017902679 905 | 904 5 0.0006700346 0.00017162134 906 | 905 5 0.00065566687 0.00019621057 907 | 906 5 0.0006372256 0.00017121341 908 | 907 5 0.00063725444 0.00018174537 909 | 908 5 0.0006145914 0.00016651441 910 | 909 5 0.0006133093 0.00016937213 911 | 910 5 0.00061961554 0.00019105565 912 | 911 5 0.0006080044 0.00017157267 913 | 912 5 0.00061321666 0.00018942141 914 | 913 5 0.00064845715 0.00018820929 915 | 914 5 0.00062990503 0.00017595394 916 | 915 5 0.00060143153 0.00017357756 917 | 916 5 0.00060286594 0.00017568556 918 | 917 5 0.0006069386 0.00016870479 919 | 918 5 0.00065214705 0.00017515349 920 | 919 5 0.0005664641 0.00016858154 921 | 920 5 0.00060280965 0.00016883157 922 | 921 5 0.00064110133 0.00016834748 923 | 922 5 0.00063520815 0.00016822113 924 | 923 5 0.0006948048 0.00017007465 925 | 924 5 0.0006237126 0.00016683676 926 | 925 5 0.0006580585 0.00017567594 927 | 926 5 0.00063748914 0.00016909406 928 | 927 5 0.00065726484 0.00022291526 929 | 928 5 0.0006058671 0.0001722893 930 | 929 5 0.00061996205 0.00018285029 931 | 930 5 0.0005942725 0.00017192303 932 | 931 5 0.0005951101 0.00025553242 933 | 932 5 0.0006238983 0.00017228608 934 | 933 5 0.0006234939 0.00016347732 935 | 934 5 0.0006124073 0.00016985401 936 | 935 5 0.0006550602 0.00016862353 937 | 936 5 0.0006383451 0.00017771673 938 | 937 5 0.000629637 0.00017824293 939 | 938 5 0.00060486584 0.0001909865 940 | 939 5 0.00065346283 0.00017885718 941 | 940 5 0.0006402128 0.00017757628 942 | 941 5 0.0005878701 0.00017615687 943 | 942 5 0.00062051544 0.00016906562 944 | 943 5 0.000582057 0.00019265717 945 | 944 5 0.0006214826 0.00016887445 946 | 945 5 0.0006032837 0.0001742022 947 | 946 5 0.0006214898 0.00016820269 948 | 947 5 0.0006214034 0.00016931452 949 | 948 5 0.00064752373 0.00017817593 950 | 949 5 0.0006139297 0.00016749684 951 | 950 5 0.00063010975 0.00019024279 952 | 951 5 0.0005954701 0.00017054453 953 | 952 5 0.0006227388 0.0001677269 954 | 953 5 0.00062780007 0.0001742071 955 | 954 5 0.0006707641 0.00017769916 956 | 955 5 0.0006322713 0.000170003 957 | 956 5 0.00062381255 0.00018129539 958 | 957 5 0.0006163941 0.00017168406 959 | 958 5 0.0005824265 0.00017751144 960 | 959 5 0.00060749 0.00016673158 961 | 960 5 0.0006026704 0.00019601715 962 | 961 5 0.0006335769 0.00016928471 963 | 962 5 0.0005960254 0.00016851316 964 | 963 5 0.00059184886 0.00017115507 965 | 964 5 0.0006274748 0.00016723426 966 | 965 5 0.0006162315 0.00017514556 967 | 966 5 0.0006202492 0.00017512382 968 | 967 5 0.00064014975 0.00018157648 969 | 968 5 0.0006146621 0.00018186845 970 | 969 5 0.0006183378 0.00018189759 971 | 970 5 0.00062781473 0.00017135438 972 | 971 5 0.00065016776 0.0001689351 973 | 972 5 0.00058144116 0.0001656128 974 | 973 5 0.0006165061 0.00021997358 975 | 974 5 0.0006099207 0.00023173675 976 | 975 5 0.0006127972 0.00016683654 977 | 976 5 0.0006277159 0.00016920913 978 | 977 5 0.00063219725 0.00016884819 979 | 978 5 0.0006238166 0.00016679383 980 | 979 5 0.00063862855 0.00021159467 981 | 980 5 0.00062389596 0.00016524676 982 | 981 5 0.00062084035 0.00017018359 983 | 982 5 0.0006499008 0.00017671018 984 | 983 5 0.0006835097 0.00020250307 985 | 984 5 0.00058544177 0.00016845886 986 | 985 5 0.0005615368 0.00016444066 987 | 986 5 0.0006603581 0.00017212139 988 | 987 5 0.00063189067 0.00017410635 989 | 988 5 0.0006221935 0.0003244321 990 | 989 5 0.0006424183 0.00017031447 991 | 990 5 0.0005952222 0.0001734286 992 | 991 5 0.00060158246 0.00016463053 993 | 992 5 0.00063737214 0.00020394556 994 | 993 5 0.00065476797 0.00017033494 995 | 994 5 0.0006271201 0.00016428575 996 | 995 5 0.0006106306 0.00018944556 997 | 996 5 0.0006124332 0.00019612971 998 | 997 5 0.00061438116 0.00018960057 999 | 998 5 0.0006303533 0.00016711325 1000 | -------------------------------------------------------------------------------- /models/ne_w64d16_v2_sigma0_30/checkpoint: -------------------------------------------------------------------------------- 1 | model_checkpoint_path: "tf_denoiser.ckpt" 2 | all_model_checkpoint_paths: "tf_denoiser.ckpt" 3 | -------------------------------------------------------------------------------- /models/ne_w64d16_v2_sigma0_30/tf_denoiser.ckpt.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/models/ne_w64d16_v2_sigma0_30/tf_denoiser.ckpt.data-00000-of-00001 -------------------------------------------------------------------------------- /models/ne_w64d16_v2_sigma0_30/tf_denoiser.ckpt.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/models/ne_w64d16_v2_sigma0_30/tf_denoiser.ckpt.index -------------------------------------------------------------------------------- /models/ne_w64d16_v2_sigma0_30/tf_denoiser.ckpt.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/models/ne_w64d16_v2_sigma0_30/tf_denoiser.ckpt.meta -------------------------------------------------------------------------------- /network_dn.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | from __future__ import print_function 3 | import torch 4 | import numpy as np 5 | from torch.autograd import Variable 6 | from torch import nn 7 | import torch.nn.functional as F 8 | 9 | debug = False 10 | 11 | EPS = 1e-4 12 | 13 | 14 | class BasicBlock(nn.Module): 15 | def __init__(self, input_dim, width, block_depth): 16 | super(BasicBlock, self).__init__() 17 | 18 | self.block_depth = block_depth 19 | 20 | self.conv1 = nn.Conv2d(input_dim, width, kernel_size=3, padding=1) 21 | if block_depth > 1: 22 | self.conv2 = nn.Conv2d(width, width, kernel_size=3, padding=1) 23 | if block_depth > 2: 24 | self.conv3 = nn.Conv2d(width, width, kernel_size=3, padding=1) 25 | if block_depth > 3: 26 | self.conv4 = nn.Conv2d(width, width, kernel_size=3, padding=1) 27 | if block_depth > 4: 28 | raise BaseException('block_depth > 4 is not implemented.') 29 | 30 | def forward(self, x): 31 | out = F.relu(self.conv1(x)) 32 | out1 = out 33 | if self.block_depth > 1: 34 | out = F.relu(self.conv2(out)) 35 | if self.block_depth > 2: 36 | out = F.relu(self.conv3(out)) 37 | if self.block_depth > 3: 38 | out = F.relu(self.conv4(out)) 39 | return out + out1 40 | 41 | 42 | 43 | 44 | class Network_dn(nn.Module): 45 | def __init__(self, block_depth=4, block_num=5, width=64, input_dim=3, min_noise_level = 0, max_noise_level = 50, 46 | btrain=False): 47 | super(Network_dn, self).__init__() 48 | 49 | self.block_depth = block_depth 50 | self.block_num = block_num 51 | self.input_dim = input_dim 52 | self.min_noise_level = min_noise_level 53 | self.max_noie_level = max_noise_level 54 | self.btrain = btrain 55 | self.width = width 56 | 57 | self.conv_first = nn.Sequential( 58 | nn.Conv2d(input_dim, width, kernel_size=3, padding=1), 59 | nn.ReLU() 60 | ) 61 | 62 | print('block depth : ', block_depth) 63 | 64 | self.conv_block_first = nn.Conv2d(width + 1, width, kernel_size=3, padding=1) 65 | self.res_block1 = BasicBlock(width+1, width, block_depth) 66 | self.res_block2 = BasicBlock(width+1, width, block_depth) 67 | self.res_block3 = BasicBlock(width+1, width, block_depth) 68 | self.res_block4 = BasicBlock(width+1, width, block_depth) 69 | self.res_block5 = BasicBlock(width+1, width, block_depth) 70 | 71 | self.conv_block_first = nn.Conv2d(width+1, width, kernel_size=3, padding=1) 72 | self.conv_last = nn.Sequential( 73 | nn.Conv2d(width, input_dim, kernel_size=3, padding=1), 74 | nn.ReLU() 75 | ) 76 | 77 | def forward(self, x, noise_level, use_scalar_noise=True): 78 | # add Gaussian noise 79 | if self.btrain and noise_level > EPS: 80 | noise = Variable(torch.randn(x.size()) * torch.from_numpy(np.float32([noise_level]))) 81 | if torch.cuda.is_available(): 82 | noise = noise.cuda() 83 | x = x + noise 84 | 85 | # construct noise layer 86 | if use_scalar_noise: 87 | [B, C, H, W] = x.size() 88 | noise_layer = torch.ones([B, 1, H, W]) * torch.from_numpy(np.float32([noise_level])) 89 | else: 90 | noise_layer = torch.from_numpy(noise_level) 91 | #print('noise_level.shape : ', noise_level.shape) 92 | 93 | noise_layer = Variable(noise_layer) 94 | if torch.cuda.is_available(): 95 | noise_layer = noise_layer.cuda() 96 | 97 | # main structure 98 | h = self.conv_first(x) 99 | for i in range(self.block_num): 100 | h = torch.cat([h, noise_layer], dim=1) 101 | if i == 0: 102 | h = self.res_block1(h) 103 | elif i == 1: 104 | h = self.res_block2(h) 105 | elif i == 2: 106 | h = self.res_block3(h) 107 | elif i == 3: 108 | h = self.res_block4(h) 109 | elif i == 4: 110 | h = self.res_block5(h) 111 | 112 | output = self.conv_last(h) 113 | return output 114 | 115 | 116 | 117 | def _cvt1(x): 118 | flag = (x > 0.04045) 119 | if torch.cuda.is_available(): 120 | flag = flag.type(torch.cuda.FloatTensor) 121 | else: 122 | flag = flag.type(torch.FloatTensor) 123 | return torch.pow((x + 0.055) / 1.055, 2.4) * flag + x / 12.92 * (1 - flag) 124 | 125 | def _cvt2(x): 126 | flag = (x > 0.008856) 127 | if torch.cuda.is_available(): 128 | flag = flag.type(torch.cuda.FloatTensor) 129 | else: 130 | flag = flag.type(torch.FloatTensor) 131 | return torch.pow(x, 1/3.0) * flag + ((7.787 * x) + 16 / 116) * (1 - flag) 132 | 133 | def rgb2lab(rgb): 134 | """ 135 | convert an image from rgb to lab in pytorch 136 | :param rgb: input image, values from [0, 1] 137 | :return: 138 | """ 139 | r = rgb[:, 0, :, :] 140 | g = rgb[:, 1, :, :] 141 | b = rgb[:, 2, :, :] 142 | 143 | # first convert rgb to xyz 144 | r = _cvt1(r) 145 | g = _cvt1(g) 146 | b = _cvt1(b) 147 | 148 | x = (r * 0.4124 + g * 0.3576 + b * 0.1805) / 0.95047 149 | y = (r * 0.2126 + g * 0.7152 + b * 0.0722) / 1.00000 150 | z = (r * 0.0193 + g * 0.1192 + b * 0.9505) / 1.08883 151 | 152 | # then convert xyz to lab 153 | x = _cvt2(x) 154 | y = _cvt2(y) 155 | z = _cvt2(z) 156 | 157 | out = rgb.clone() 158 | out[:, 0, :, :] = (116 * y) - 16 159 | out[:, 1, :, :] = 500 * (x - y) 160 | out[:, 2, :, :] = 200 * (y - z) 161 | return out 162 | 163 | if __name__ == '__main__': 164 | import torch 165 | from torch.autograd import Variable 166 | 167 | image = Variable(torch.randn(5, 3, 128, 128)) 168 | network = Network_dn(n_low=3, n_high=3) 169 | output = network(image) 170 | print('output.shape : ', output.shape) 171 | 172 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /res/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/.DS_Store -------------------------------------------------------------------------------- /res/chen+dn/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/.DS_Store -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim01.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim02.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim03.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim04.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim05.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim06.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim07.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim08.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim09.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim10.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim11.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim12.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim13.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim14.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim15.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim16.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim17.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim18.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim19.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim20.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim21.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim22.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim23.png -------------------------------------------------------------------------------- /res/chen+dn/kodak_sigma15/kodim24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/chen+dn/kodak_sigma15/kodim24.png -------------------------------------------------------------------------------- /res/drne+dn/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/.DS_Store -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim01.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim02.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim03.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim04.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim05.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim06.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim07.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim08.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim09.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim10.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim11.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim12.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim13.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim14.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim15.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim16.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim17.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim18.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim19.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim20.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim21.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim22.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim23.png -------------------------------------------------------------------------------- /res/drne+dn/kodak_sigma15/kodim24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TomHeaven/Pixel-wise-Estimation-of-Signal-Dependent-Image-Noise-using-Deep-Residual-Learning/7f2a57312f7cec76e5d7016825f75ee9bbd170f5/res/drne+dn/kodak_sigma15/kodim24.png -------------------------------------------------------------------------------- /test_chen_and_dn.py: -------------------------------------------------------------------------------- 1 | # coding=utf8 2 | # Author: TomHeaven, hanlin_tan@nudt.edu.cn, 2017.08.19 3 | 4 | from __future__ import print_function 5 | from tensorflow.contrib.layers import conv2d, avg_pool2d 6 | import tensorflow as tf 7 | import numpy as np 8 | from data_v3 import DatabaseCreator 9 | import time 10 | import tqdm 11 | import cv2 12 | import re 13 | import os 14 | import argparse 15 | import h5py 16 | from multiprocessing import Process 17 | 18 | # options 19 | DEBUG = False 20 | 21 | from drdd_dn_sigma0_50 import DeepProcesser 22 | 23 | 24 | 25 | def test_denoise(input_folder, sigma_folder, output_folder, model_dir, block_num, width, block_depth, device): 26 | ## denoise 27 | os.environ['CUDA_VISIBLE_DEVICES'] = device 28 | deepProcesser = DeepProcesser(block_num=block_num, width=width, block_depth=block_depth, 29 | use_scalar_noise=True) 30 | deepProcesser.load_model(model_dir, False) 31 | 32 | regexp = re.compile(r'.*\.(%s)' % '(tif|tiff|jpg|png)') 33 | if not os.path.isdir(output_folder): 34 | os.mkdir(output_folder) 35 | 36 | psize = 250 37 | max_value = 255.0 38 | 39 | crop = 0 40 | n = 0 41 | 42 | for d, dirs, files in os.walk(input_folder): 43 | for f in files: 44 | if regexp.match(f): 45 | print('image', n, f) 46 | image = cv2.imread(os.path.join(d, f)) 47 | 48 | if DEBUG: 49 | print('image.shape : ', image.shape) 50 | 51 | image = image / max_value 52 | with open('%s/%s_chen.txt' % (sigma_folder, f), 'r') as sigma_file: 53 | str = sigma_file.readline() 54 | noise_level = np.float32(str) 55 | print('noise_level : ', noise_level) 56 | 57 | R, runtime = deepProcesser.test(image, noise_level / 255.0, psize, crop) 58 | out = np.uint8(R * 255 + 0.5) 59 | 60 | # R = swap_blue_red(R) 61 | 62 | if DEBUG: 63 | print('max value = ', np.max(np.abs(R))) 64 | print('time : ', runtime, ' ms') 65 | 66 | cv2.imwrite(os.path.join(output_folder, f), out) 67 | n += 1 68 | 69 | if __name__ == '__main__': 70 | ## configuration 71 | device = '1' 72 | # datasets: 'kodak', 'mcm', 'bsd500' sigma 5, 15, 25 73 | methods = ['drne+dn', 'chen+dn'] 74 | datasets = ['kodak', 'mcm', 'bsd500'] 75 | #sigmas = [5, 15, 25] 76 | sigmas = [15] 77 | 78 | 79 | for d in datasets: 80 | print(' Dataset : ', d) 81 | for s in sigmas: 82 | print(' Sigma : ', s) 83 | 84 | input_folder = 'data/%s_sigma%d' % (d, s) 85 | sigma_folder = 'data/chen/%s_sigma%d' %(d, s) 86 | output_folder= 'res/chen+dn/%s_sigma%d' %(d, s) 87 | #### end configuration 88 | 89 | # denoise 90 | modelPath = 'dn_sigma0_50' 91 | block_num = 5 92 | block_depth = 4 93 | width = 64 94 | 95 | # 用子进程启动 Pytorch,退出时可完全释放显存 96 | p = Process(target=test_denoise, args=( 97 | input_folder, sigma_folder, output_folder, 'models/%s' % modelPath, block_num, width, block_depth, device)) 98 | p.start() 99 | p.join() # this blocks until the process terminates 100 | #test_denoise(input_folder, sigma_folder, output_folder, 'models/%s' % modelPath, block_num, width, block_depth, device=device) -------------------------------------------------------------------------------- /test_drne_and_dn.py: -------------------------------------------------------------------------------- 1 | # coding=utf8 2 | # Author: TomHeaven, hanlin_tan@nudt.edu.cn, 2017.08.19 3 | 4 | from __future__ import print_function 5 | from tensorflow.contrib.layers import conv2d, avg_pool2d 6 | import tensorflow as tf 7 | import numpy as np 8 | from data_v3 import DatabaseCreator 9 | import time 10 | import tqdm 11 | import cv2 12 | import re 13 | import os 14 | import argparse 15 | import h5py 16 | from multiprocessing import Process 17 | 18 | # options 19 | DEBUG = False 20 | 21 | from model_noise_estimation_w64d16_v2_sigma0_30 import Estimator 22 | from drdd_dn_sigma0_50 import DeepProcesser 23 | 24 | 25 | 26 | def test_estimate(input_folder, modelPath, feature_dim, depth, device): 27 | """ 28 | Denoise noisy images using Estimator class with pre-trained model. 29 | :param modelPath: path to save trained model 30 | :param feature_dim: width of the DNN 31 | :param depth: depth of the DNN 32 | :param device: which GPU to use (for machines with multiple GPUs, this avoid taking up all GPUs) 33 | :param noise: standard variation of noise of the tested images 34 | :return: 35 | """ 36 | os.environ['CUDA_VISIBLE_DEVICES'] = device 37 | estimator = Estimator(batchSize=1, feature_dim=feature_dim, depth=depth) 38 | regexp = re.compile(r'.*\.(%s)' % '(jpg)|(png)|(bmp)|(tif)') 39 | #input_folder = 'data/mcm' 40 | 41 | psize = 250 42 | max_value = 255.0 43 | 44 | crop = 0 45 | n = 0 46 | 47 | avg_en = 0 48 | 49 | outFile = h5py.File('data/ne_res.h5', "w") 50 | 51 | for d, dirs, files in os.walk(input_folder): 52 | for f in files: 53 | if regexp.match(f): 54 | print('image', n, f) 55 | 56 | image = cv2.imread(os.path.join(d, f)) 57 | #image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) 58 | if DEBUG: 59 | print ('image.shape : ', image.shape) 60 | 61 | if n == 0: 62 | xshape = [psize, psize, 3] 63 | yshape = [psize, psize, 3] 64 | estimator.load_model(modelPath, batchSize=1, xshape = xshape, yshape=yshape) 65 | 66 | 67 | image = image / max_value 68 | R, runtime = estimator.denoise_bayer(image, psize, crop) 69 | estimated_noise = np.mean(np.mean(np.mean(R, axis=0), axis=0), axis=0) 70 | 71 | if DEBUG: 72 | print('max value = ', np.max(np.abs(R))) 73 | print('time : ', runtime, ' ms') 74 | 75 | outFile.create_dataset('noise_estimation_%d' % n, data=np.mean(R, axis=2), compression='gzip') 76 | #outFile.create_dataset('runtime_%d' % n, data=R * 255, compression='gzip') 77 | print('estimate_noise : ', estimated_noise * 255.0) 78 | n += 1 79 | avg_en += estimated_noise 80 | 81 | outFile.close() 82 | print('avg_en : ', avg_en / n * 255.0) 83 | estimator.sess.close() 84 | 85 | def test_denoise(input_folder, output_folder, model_dir, block_num, width, block_depth, device): 86 | ## denoise 87 | os.environ['CUDA_VISIBLE_DEVICES'] = device 88 | deepProcesser = DeepProcesser(block_num=block_num, width=width, block_depth=block_depth, 89 | use_scalar_noise=False) 90 | deepProcesser.load_model(model_dir, False) 91 | 92 | regexp = re.compile(r'.*\.(%s)' % '(tif|tiff|jpg|png)') 93 | if not os.path.isdir(output_folder): 94 | os.mkdir(output_folder) 95 | 96 | psize = 250 97 | max_value = 255.0 98 | 99 | crop = 0 100 | n = 0 101 | 102 | nl_file = h5py.File('data/ne_res.h5', "r") 103 | 104 | for d, dirs, files in os.walk(input_folder): 105 | for f in files: 106 | if regexp.match(f): 107 | print('image', n, f) 108 | image = cv2.imread(os.path.join(d, f)) 109 | 110 | if DEBUG: 111 | print('image.shape : ', image.shape) 112 | 113 | image = image / max_value 114 | 115 | noise = nl_file['noise_estimation_%d' % n].value 116 | #print('noise.shape : ', noise.shape) 117 | #noise = noise.transpose(2, 0, 1) 118 | noise = noise[np.newaxis, np.newaxis, ...] 119 | 120 | R, runtime = deepProcesser.test(image, noise, psize, crop) 121 | out = np.uint8(R * 255 + 0.5) 122 | 123 | # R = swap_blue_red(R) 124 | 125 | if DEBUG: 126 | print('max value = ', np.max(np.abs(R))) 127 | print('time : ', runtime, ' ms') 128 | 129 | cv2.imwrite(os.path.join(output_folder, f), out) 130 | n += 1 131 | 132 | if __name__ == '__main__': 133 | ## configuration 134 | device = '1' 135 | # datasets: 'kodak', 'mcm', 'bsd500' sigma 5, 15, 25 136 | 137 | datasets = ['kodak', 'mcm', 'bsd500'] 138 | #sigmas = [5, 15, 25] 139 | sigmas = [15] 140 | 141 | 142 | for d in datasets: 143 | print(' Dataset : ', d) 144 | for s in sigmas: 145 | print(' Sigma : ', s) 146 | 147 | input_folder = 'data/%s_sigma%d' % (d, s) 148 | output_folder= 'res/drne+dn/%s_sigma%d' % (d, s) 149 | # estimation 150 | modelPath = 'ne_w64d16_v2_sigma0_30' 151 | width = 64 152 | depth = 16 - 4 153 | minNoiseLevel = 0.0 / 255.0 154 | maxNoiseLevel = 30.0 / 255.0 155 | #### end configuration 156 | 157 | # 用子进程启动 Tensorflow,退出时可完全释放显存 158 | p = Process(target=test_estimate, args=(input_folder, 'models/%s' % modelPath, width, depth, device)) 159 | p.start() 160 | p.join() # this blocks until the process terminates 161 | #test_estimate(input_folder, 'models/%s' % modelPath, width, depth=depth, device=device) 162 | 163 | # denoise 164 | modelPath = 'dn_sigma0_50' 165 | block_num = 5 166 | block_depth = 4 167 | width = 64 168 | # 用子进程启动 Pytorch,退出时可完全释放显存 169 | p = Process(target=test_denoise, args=(input_folder, output_folder, 'models/%s' % modelPath, block_num, width, block_depth, device)) 170 | p.start() 171 | p.join() # this blocks until the process terminates 172 | #test_denoise(input_folder, output_folder, 'models/%s' % modelPath, block_num, width, block_depth, device=device) --------------------------------------------------------------------------------