├── +CE ├── TestImage.m └── TestReport.m ├── .gitignore ├── LICENSE ├── README.md ├── others ├── +JED │ ├── JED.p │ └── rgb2yuv.m ├── amsr.m ├── bpdhe.m ├── colorBalance.m ├── dheci.m ├── dong.m ├── he.m ├── jed.m ├── multiscaleRetinex.m ├── private │ ├── build_is_hist.m │ └── lowlight_enhancement.p └── robustRetinex.m ├── ours ├── Ying_2017_CAIP.m └── Ying_2017_ICCV.m └── ref.bib /+CE/TestImage.m: -------------------------------------------------------------------------------- 1 | classdef TestImage < handle 2 | %TestImage help you test the performance of image enhancement algorithms. 3 | %Example 4 | % Test = CE.TestImage('pout.tif'); % specify datasets 5 | % Test.Method = {@imadjust, @imsharpen}; % specify methods to evaluate 6 | % Test.Metric = {@psnr, @ssim}; % specify evaluate metrics 7 | % Test, % run test and show result 8 | % save(Test); % save results 9 | 10 | properties 11 | Method = {} 12 | Metric = {} 13 | MethodCache = {} 14 | MetricCache = {} 15 | OutName = '__.PNG'; 16 | OutDir = '/out'; % output result images 17 | 18 | %append = true; % append result if true, overwrite result if false. 19 | 20 | %tbl 21 | Report % = CE.TestReport([]) 22 | Files 23 | DataDir % dataset folder 24 | 25 | LoadRaw = @(f)im2double(imread(f)) % filename 26 | LoadRes = @(f)im2double(imread(f)) 27 | LoadRef = @(f)im2double(imread(f)) % preprocessing file when evaluating 28 | end 29 | 30 | properties (Constant) 31 | ReportFile = '/out/TestReport.csv'; 32 | CellStr = @(cellFun)cellfun(@char, cellFun, 'UniformOutput', false); 33 | CellFun = @(cellStr)cellfun(@str2func, cellStr, 'UniformOutput', false); 34 | end 35 | 36 | methods(Access = public) 37 | function this = addMethod(this, varargin), this.Method = this.CellFun( union(this.CellStr(this.Method), this.CellStr(varargin))); end%this.Method = [this.Method; varargin']; end 38 | function this = addMetric(this, varargin), this.Metric = this.CellFun( union(this.CellStr(this.Metric), this.CellStr(varargin))); end%this.Metric = [this.Metric; varargin']; end 39 | function this = delMethod(this, varargin), this.Method = this.CellFun( setdiff(this.CellStr(this.Method), this.CellStr(varargin))); end 40 | function this = delMetric(this, varargin), this.Metric = this.CellFun( setdiff(this.CellStr(this.Metric), this.CellStr(varargin))); end 41 | 42 | function delResult(this, varargin) 43 | outDir = strrep(this.OutDir, '', this.DataDir); 44 | for n = 1:numel(varargin) 45 | outName = strrep(this.OutName, '', '*'); 46 | outName = strrep(outName, '', '*'); 47 | outName = strrep(outName, '', char(varargin{n})); 48 | eachfile([outDir filesep outName], @delete); 49 | end 50 | end 51 | end 52 | 53 | methods 54 | function this = TestImage(images, varargin) 55 | this.Files = eachfile(images); 56 | if isempty(this.Files) 57 | error 'no file found in this dataset.' 58 | else 59 | this.DataDir = fileparts(this.Files{1}); % images 60 | end 61 | 62 | % load configuation 63 | for n = 1:2:numel(varargin)-1 64 | this.(varargin{n}) = varargin{n+1}; 65 | end 66 | 67 | % load cached 68 | reportFile = strrep(this.ReportFile, '', this.DataDir); 69 | if exist(reportFile, 'file'), this.load(reportFile); end 70 | end 71 | 72 | function this = load(this, file) 73 | import CE.TestReport 74 | 75 | fprintf('Loading... %s \n', file); 76 | this.Report = TestReport(file); 77 | disp 'Done Loading.' 78 | 79 | this.MethodCache = this.CellFun(this.Report.Method); 80 | this.MetricCache = this.CellFun(this.Report.Metric); 81 | this.Method = this.MethodCache; 82 | this.Metric = this.MetricCache; 83 | end 84 | 85 | function save(this, file) 86 | if nargin < 2 87 | file = strrep(this.ReportFile, '', this.DataDir); 88 | if exist(file, 'file') % backup 89 | movefile(file, rename(file, '/__%s.', datestr(now,'yyyy-mm-dd_HH-MM-SS.FFF'))); 90 | end 91 | end 92 | writetable(this.Report.Data, file); 93 | end 94 | 95 | function report = runtest(this, methods, metrics) 96 | % here methods and metrics are cell string 97 | import CE.TestReport 98 | outDir = strrep(this.OutDir, '', this.DataDir); 99 | if ~isdir(outDir), mkdir(outDir); end 100 | 101 | reportFile = strrep([this.ReportFile '__tmp.txt'], '', this.DataDir); % tempfile 102 | %if ~isdir(fileparts(reportFile)), mkdir(fileparts(reportFile)); end 103 | 104 | fid = fopen(reportFile, 'w'); 105 | fprintf(fid, 'File\tMethod\t%s\n', strjoin(metrics, '\t')); % heading 106 | 107 | fprintf('Testing %s \n', this.DataDir); 108 | eachfile(this.Files, @onSingleFile); 109 | fprintf('Done Testing %s \n', this.DataDir); 110 | 111 | fclose(fid); 112 | fprintf('Benchmark Result see: %s\n', reportFile); 113 | report = TestReport(readtable(reportFile, 'Delimiter','\t')); 114 | 115 | function onSingleFile(inFile) 116 | %this.rawFile = inFile; 117 | %globalVar('Test_fileName', inFileName); 118 | % heading 119 | fprintf('Method\t\t\t'); fprintf('%9s\t', metrics{:}); fprintf('\n'); 120 | 121 | for m = methods(:)', method = m{1}; 122 | [~, name, ext] = fileparts(inFile); 123 | outName = strrep(this.OutName, '', name); 124 | outName = strrep(outName, '', ext(2:end)); 125 | outName = strrep(outName, '', char(method)); 126 | outFile = [outDir filesep outName]; 127 | 128 | % regenerate results if it is not exist 129 | if ~exist(outFile, 'file') 130 | fprintf('Regenerate file: %s\n', outFile); 131 | func = str2func(method); 132 | res = func(this.LoadRaw(inFile)); 133 | imwrite(im2double(res), outFile); 134 | end 135 | 136 | % load result file and compute metrics 137 | ref = this.LoadRef(inFile); 138 | res = this.LoadRes(outFile); 139 | 140 | globalVar('Test_resultFile', outFile); 141 | 142 | fprintf(fid, '%s\t%s', [name, ext], method); fprintf('%8s\t', method); 143 | 144 | for n = metrics(:)', metric = n{1}; % if eval exist, then do it 145 | func = str2func(metric); 146 | try % allow two or one input 147 | marks = func(res, ref); 148 | catch ME 149 | switch ME.identifier 150 | case {'MATLAB:TooManyInputs', 'MATLAB:narginchk:tooManyInputs'} 151 | marks = func(res); 152 | otherwise 153 | ME.identifier, rethrow(ME) 154 | end 155 | end 156 | fprintf(fid, '\t%f', marks); fprintf('\t\t%.2f', marks); 157 | end 158 | fprintf(fid, '\n'); fprintf('\n'); 159 | end 160 | end 161 | end 162 | 163 | function disp(this) 164 | method = this.CellStr(this.Method); 165 | metric = this.CellStr(this.Metric); 166 | methodCache = this.CellStr(this.MethodCache); 167 | metricCache = this.CellStr(this.MetricCache); 168 | 169 | if isempty(this.Report) 170 | this.Report = this.runtest(method, metric); 171 | else 172 | [oldMethod,indexMethodCache] = intersect(methodCache, method); 173 | [oldMetric,indexMetricCache] = intersect(metricCache, metric); 174 | newMethod = setdiff(method, methodCache); 175 | newMetric = setdiff(metric, metricCache); 176 | 177 | this.Report = this.Report(indexMethodCache', indexMetricCache'); 178 | if ~isempty(newMethod) 179 | this.Report = vertcat(this.Report, this.runtest(newMethod, oldMetric)); end 180 | if ~isempty(newMetric) 181 | this.Report = horzcat(this.Report,this.runtest([oldMethod, newMethod], newMetric)); end 182 | end 183 | 184 | this.MethodCache = this.Method; 185 | this.MetricCache = this.Metric; 186 | 187 | fprintf('Test Report: %s \n', this.DataDir); 188 | disp(this.Report); 189 | end 190 | end 191 | methods (Access = private) 192 | 193 | end 194 | end 195 | 196 | -------------------------------------------------------------------------------- /+CE/TestReport.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidut/OpenCE/abbc8609b7d5069e20871b585dcf6d18b59f1c0e/+CE/TestReport.m -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *wiki* 2 | \#* 3 | \#dataset/ 4 | \#include/ 5 | \#toolbox/ 6 | *.zip 7 | *out* 8 | dev 9 | *junk* 10 | *temp* 11 | *test*.txt 12 | *.asv 13 | *.mlx 14 | *out* -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Zhenqiang.Ying 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 | # OpenCE 2 | Contrast Enhancement Techniques 3 | 4 | ## Methods 5 | 6 | ### Lowlight Image Enhancement 7 | 8 | * HE-based 9 | * BPDHE `bpdhe` 10 | * DHE A Dynamic Histogram Equalization for Image Contrast Enhancement IEEE TCE 2007 11 | * DHECI 12 | * CLAHE (Contrast-limited adaptive histogram equalization) `clahe` `clahe_lab ` 13 | * WAHE (Weighted Approximated Histogram Equalization) 14 | * CVC (Contextual and Variational Contrast enhancement) [PDF](http://ieeexplore.ieee.org/abstract/document/5773086/) 15 | * LDR (Layered Difference Representation) [website](http://mcl.korea.ac.kr/cwlee_tip2013/) (CVC, WAHE) 16 | * Retinex-based 17 | * AMSR 18 | * LIME [website](http://cs.tju.edu.cn/orgs/vision/~xguo/LIME.htm) 19 | * NPE [website](http://blog.sina.com.cn/s/blog_a0a06f190101cvon.html) 20 | * SRIE (Simultaneous Reflection and Illumination Estimation) [CVPR2016](http://www.cv-foundation.org/openaccess/content_cvpr_2016/html/Fu_A_Weighted_Variational_CVPR_2016_paper.html) [website](http://smartdsp.xmu.edu.cn/cvpr2016.html) 21 | * MF (Multi-deviation Fusion method) [website](http://smartdsp.xmu.edu.cn/weak-illumination.html) 22 | * `others/robustRetinex.m` Structure-Revealing Low-Light Image Enhancement Via Robust Retinex Model (TIP 2018) [website](https://github.com/martinli0822/Low-light-image-enhancement) 23 | * Dehaze-based 24 | * Dong 25 | * Camera-Response-Model-based 26 | * [Ying_2017_ICCV.m](https://github.com/baidut/OpenCE/blob/master/ours/Ying_2017_ICCV.m) 27 | * Fusion-based 28 | * [Ying_2017_CAIP.m ](https://github.com/baidut/OpenCE/blob/master/ours/Ying_2017_CAIP.m) [python version](https://github.com/AndyHuang1995/New-Image-Contrast-Enhancement) 29 | * Deep-learning-based 30 | * Learning a Deep Single Image Contrast Enhancer from Multi-Exposure Images *TIP 2018* [website](https://github.com/csjcai/SICE) 31 | * Others 32 | * `others/jed.m` JED "[Joint Enhancement and Denoising Method via Sequential Decomposition](http://www.icst.pku.edu.cn/course/icb/Projects/JED.html)" , *ISCAS 2018* [website](https://github.com/tonghelen/JED-Method) 33 | 34 | ### Related Work 35 | 36 | - [Fast Image Processing with Fully-Convolutional Networks (ICCV 2017)](http://www.cqf.io/papers/Fast_Image_Processing_ICCV2017.pdf) () 37 | - [Deep Bilateral Learning for Real-Time Image Enhancements (Siggraph 2017)](https://groups.csail.mit.edu/graphics/hdrnet/data/hdrnet.pdf) () 38 | 39 | ## Test Images 40 | 41 | - 500 from [Berkeley Segmentation Data Set and Benchmarks 500 (BSDS500)](http://www.eecs.berkeley.edu/Research/Projects/CS/vision/grouping/resources.html#bsds500) 42 | - 24 from [Kodak Lossless True Color Image Suite](http://r0k.us/graphics/kodak/) 43 | - 7 of 4.2.0x from [The USCI-SIPI Image Database, Volume 3: Miscellaneous](http://sipi.usc.edu/database/database.php?volume=misc) 44 | - 69 captured images from commercial digital cameras: [Download (15.3 MB)](http://mcl.korea.ac.kr/projects/LDR/LDR_TEST_IMAGES_DICM.zip) 45 | - 4 synthetic images: [Download (445 kB)](http://mcl.korea.ac.kr/projects/LDR/LDR_TEST_IMAGES_SYNTHETIC.zip) 46 | 47 | 48 | 49 | ## Metrics 50 | 51 | - entropy (DE) 52 | - EME 53 | - AB 54 | - PixDist 55 | - LOE 56 | 57 | ## Publications 58 | 59 | Source code can be found at `ours` folder: 60 | 61 | 1. A New Image Contrast Enhancement Algorithm using Exposure Fusion Framework (accepted by CAIP 2017,journal version submitted to IEEE Transactions on Cybernetics) [project website](https://baidut.github.io/OpenCE/caip2017.html) 62 | 63 | 64 | 2. A New Low-Light Image Enhancement Algorithm using Camera Response Model (accepted by ICCV Workshop 2017) 65 | 66 | ## Citations 67 | 68 | ``` 69 | @inproceedings{fu2016srie, 70 | title={A weighted variational model for simultaneous reflectance and illumination estimation}, 71 | author={Fu, Xueyang and Zeng, Delu and Huang, Yue and Zhang, Xiao-Ping and Ding, Xinghao}, 72 | booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition}, 73 | pages={2782--2790}, 74 | year={2016} 75 | } 76 | @article{celik2011cvc, 77 | title={Contextual and variational contrast enhancement}, 78 | author={Celik, Turgay and Tjahjadi, Tardi}, 79 | journal={IEEE Transactions on Image Processing}, 80 | volume={20}, 81 | number={12}, 82 | pages={3431--3441}, 83 | year={2011}, 84 | publisher={IEEE} 85 | } 86 | @inproceedings{lee2012ldr, 87 | title={Contrast enhancement based on layered difference representation}, 88 | author={Lee, Chulwoo and Lee, Chul and Kim, Chang-Su}, 89 | booktitle={Image Processing (ICIP), 2012 19th IEEE International Conference on}, 90 | pages={965--968}, 91 | year={2012}, 92 | organization={IEEE} 93 | } 94 | @article{arici2009wahe, 95 | title={A histogram modification framework and its application for image contrast enhancement}, 96 | author={Arici, Tarik and Dikbas, Salih and Altunbasak, Yucel}, 97 | journal={IEEE Transactions on image processing}, 98 | volume={18}, 99 | number={9}, 100 | pages={1921--1935}, 101 | year={2009}, 102 | publisher={IEEE} 103 | } 104 | @article{fu2016mf, 105 | title={A fusion-based enhancing method for weakly illuminated images}, 106 | author={Fu, Xueyang and Zeng, Delu and Huang, Yue and Liao, Yinghao and Ding, Xinghao and Paisley, John}, 107 | journal={Signal Processing}, 108 | volume={129}, 109 | pages={82--96}, 110 | year={2016}, 111 | publisher={Elsevier} 112 | } 113 | @article{ibrahim2007bpdhe, 114 | title={Brightness preserving dynamic histogram equalization for image contrast enhancement}, 115 | author={Ibrahim, Haidi and Kong, Nicholas Sia Pik}, 116 | journal={IEEE Transactions on Consumer Electronics}, 117 | volume={53}, 118 | number={4}, 119 | pages={1752--1758}, 120 | year={2007}, 121 | publisher={IEEE} 122 | } 123 | @inproceedings{lee2013amsr, 124 | title={Adaptive multiscale retinex for image contrast enhancement}, 125 | author={Lee, Chang-Hsing and Shih, Jau-Ling and Lien, Cheng-Chang and Han, Chin-Chuan}, 126 | booktitle={Signal-Image Technology \& Internet-Based Systems (SITIS), 2013 International Conference on}, 127 | pages={43--50}, 128 | year={2013}, 129 | organization={IEEE} 130 | } 131 | @inproceedings{dong2011fast, 132 | title={Fast efficient algorithm for enhancement of low lighting video}, 133 | author={Dong, Xuan and Wang, Guan and Pang, Yi and Li, Weixin and Wen, Jiangtao and Meng, Wei and Lu, Yao}, 134 | booktitle={2011 IEEE International Conference on Multimedia and Expo}, 135 | pages={1--6}, 136 | year={2011}, 137 | organization={IEEE} 138 | } 139 | @inproceedings{nakai2013dheci, 140 | title={Color image contrast enhacement method based on differential intensity/saturation gray-levels histograms}, 141 | author={Nakai, Keita and Hoshi, Yoshikatsu and Taguchi, Akira}, 142 | booktitle={Intelligent Signal Processing and Communications Systems (ISPACS), 2013 International Symposium on}, 143 | pages={445--449}, 144 | year={2013}, 145 | organization={IEEE} 146 | } 147 | @article{Cai2018deep, 148 | title={Learning a Deep Single Image Contrast Enhancer from Multi-Exposure Images}, 149 | author={Cai, Jianrui and Gu, Shuhang and Zhang, Lei}, 150 | journal={IEEE Transactions on Image Processing}, 151 | volume={27}, 152 | number={4}, 153 | pages={2049-2062}, 154 | year={2018}, 155 | publisher={IEEE} 156 | } 157 | ``` 158 | 159 | **Please feel free to contact me (yingzhenqiang-at-gmail-dot-com) if you have any further questions or concerns.** -------------------------------------------------------------------------------- /others/+JED/JED.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidut/OpenCE/abbc8609b7d5069e20871b585dcf6d18b59f1c0e/others/+JED/JED.p -------------------------------------------------------------------------------- /others/+JED/rgb2yuv.m: -------------------------------------------------------------------------------- 1 | function Z= rgb2yuv(img) 2 | 3 | % [w h d]=size(img); 4 | % img=double(img); 5 | % Z=zeros(w,h,d); 6 | % A=[0.299,0.587,0.114;-0.14713,-0.28886,0.436;0.615,-0.51499,-0.10001]; 7 | % 8 | % for i=1:w 9 | % for j=1:h 10 | % Z(i,j,:)=A*reshape(img(i,j,:),[3 1]); 11 | % end 12 | % end 13 | 14 | T = [0.299,0.587,0.114;-0.169,-0.331,0.5;0.5,-0.419,-0.081]'; 15 | 16 | [h w r] = size(img); 17 | 18 | temp = double(reshape(img, h*w, r)); 19 | gray = double(ones(h*w,r)*128); 20 | gray(:,1) = 0; 21 | temp = temp*T+gray; 22 | Z = reshape(temp, h, w, r); 23 | 24 | end -------------------------------------------------------------------------------- /others/amsr.m: -------------------------------------------------------------------------------- 1 | function d = amsr(im,sigma1,sigma2,sigma3) 2 | 3 | if ~exist('sigma1','var'),sigma1 = 15;end 4 | if ~exist('sigma2','var'),sigma2 = 80;end 5 | if ~exist('sigma3','var'),sigma3 = 250;end 6 | 7 | im = im2double(im); % double --> im2double 8 | gausKernel1 = fspecial('gaussian',[sigma1 sigma1],5); 9 | gausKernel2 = fspecial('gaussian',[sigma2 sigma2],20); 10 | gausKernel3 = fspecial('gaussian',[sigma3 sigma3],50); 11 | Y = 0.299.*im(:,:,1)+0.587.*im(:,:,2)+0.114.*im(:,:,3); 12 | 13 | blur_im1 = (imfilter(Y,gausKernel1,'replicate')); 14 | blur_im2 = (imfilter(Y,gausKernel2,'replicate')); 15 | blur_im3 = (imfilter(Y,gausKernel3,'replicate')); 16 | 17 | Y_ssr1 = log(Y) - log(blur_im1); 18 | Y_ssr2 = log(Y) - log(blur_im2); 19 | Y_ssr3 = log(Y) - log(blur_im3); 20 | 21 | sr = sort(Y_ssr1(:)); 22 | p1 = sr(uint32(0.01*size(im,1)*size(im,2))); 23 | p99 = sr(uint32(0.99*size(im,1)*size(im,2))); 24 | lc1 = Y_ssr1 >= p1 & Y_ssr1 <= p99; 25 | lc2 = Y_ssr1 < p1; 26 | lc3 = Y_ssr1 > p99; 27 | Y_ssr1(lc1) = 255 * (Y_ssr1(lc1)-p1)./(p99-p1); 28 | Y_ssr1(lc2) = 0; 29 | Y_ssr1(lc3) = 255; 30 | 31 | sr = sort(Y_ssr2(:)); 32 | p1 = sr(uint32(0.01*size(im,1)*size(im,2))); 33 | p99 = sr(uint32(0.99*size(im,1)*size(im,2))); 34 | lc1 = Y_ssr2 >= p1 & Y_ssr2 <= p99; 35 | lc2 = Y_ssr2 < p1; 36 | lc3 = Y_ssr2 > p99; 37 | Y_ssr2(lc1) = 255 * (Y_ssr2(lc1)-p1)./(p99-p1); 38 | Y_ssr2(lc2) = 0; 39 | Y_ssr2(lc3) = 255; 40 | 41 | sr = sort(Y_ssr3(:)); 42 | p1 = sr(uint32(0.01*size(im,1)*size(im,2))); 43 | p99 = sr(uint32(0.99*size(im,1)*size(im,2))); 44 | lc1 = Y_ssr3 >= p1 & Y_ssr3 <= p99; 45 | lc2 = Y_ssr3 < p1; 46 | lc3 = Y_ssr3 > p99; 47 | Y_ssr3(lc1) = 255 * (Y_ssr3(lc1)-p1)./(p99-p1); 48 | Y_ssr3(lc2) = 0; 49 | Y_ssr3(lc3) = 255; 50 | 51 | % Y = 0.299.*im(:,:,1)+0.587.*im(:,:,2)+0.114.*im(:,:,3); 52 | % Y_ssr1 = 0.299.*R_ssr1(:,:,1)+0.587.*R_ssr1(:,:,2)+0.114.*R_ssr1(:,:,3); 53 | % Y_ssr2 = 0.299.*R_ssr2(:,:,1)+0.587.*R_ssr2(:,:,2)+0.114.*R_ssr2(:,:,3); 54 | % Y_ssr3 = 0.299.*R_ssr3(:,:,1)+0.587.*R_ssr3(:,:,2)+0.114.*R_ssr3(:,:,3); 55 | sigma = 32; 56 | mu0 = 32; 57 | mu1 = 96; 58 | mu2 = 160; 59 | mu3 = 224; 60 | P0 = exp(-(Y-mu0).^2./(2*sigma^2)); 61 | P1 = exp(-(Y-mu1).^2./(2*sigma^2)); 62 | P2 = exp(-(Y-mu2).^2./(2*sigma^2)); 63 | P3 = max(P0,exp(-(Y-mu3).^2./(2*sigma^2))); 64 | psum = P0+P1+P2+P3; 65 | omega0 = P0./psum; 66 | omega1 = P1./psum; 67 | omega2 = P2./psum; 68 | omega3 = P3./psum; 69 | Y_amsr = omega0.*Y + omega1.*Y_ssr1 + omega2.*Y_ssr2 + omega3.*Y_ssr3; 70 | ratio = Y_amsr./Y; 71 | 72 | % modified: uint8 --> im2uint8 73 | hsv = rgb2hsv(im2uint8(im)); 74 | v = hsv(:,:,3);%.*255; 75 | v = 0.5.*(ratio.*(v+Y)+v-Y); 76 | hsv(:,:,3) = v./255; 77 | %d = uint8(hsv2rgb(hsv).*255); 78 | d = double(hsv2rgb(hsv)); % modified 79 | d = min(max(d,0),1); % add 80 | 81 | % r = 0.5.*(ratio.*(im(:,:,1)+Y)+im(:,:,1)-Y); 82 | % g = 0.5.*(ratio.*(im(:,:,2)+Y)+im(:,:,2)-Y); 83 | % b = 0.5.*(ratio.*(im(:,:,3)+Y)+im(:,:,3)-Y); 84 | % d = cat(3,r,g,b)./255; 85 | end -------------------------------------------------------------------------------- /others/bpdhe.m: -------------------------------------------------------------------------------- 1 | function d = bpdhe(im) 2 | 3 | im = im2uint8(im); 4 | 5 | hsv = rgb2hsv(im); 6 | h = hsv(:,:,1); 7 | s = hsv(:,:,2); 8 | i = uint8(hsv(:,:,3).*255); 9 | % i = uint8(20+rand(512).*(200)); 10 | ma = double(max(i(:))); 11 | mi = double(min(i(:))); 12 | bins = (ma-mi)+1; 13 | hist_i = hist(double(i(:)),bins); 14 | gausFilter = fspecial('gaussian',[1 9],1.0762); 15 | blur_hist = (imfilter(hist_i,gausFilter,'replicate')); 16 | derivFilter = [-1 1]; 17 | deriv_hist = imfilter(blur_hist,derivFilter,'replicate'); 18 | sign_hist = sign(deriv_hist); 19 | meanFilter = [1/3 1/3 1/3]; 20 | smooth_sign_hist = sign(imfilter(sign_hist,meanFilter,'replicate')); 21 | cmpFilter = [1 1 1 -1 -1 -1 -1 -1]; 22 | index = zeros([1,3]); 23 | index(1) = 0; 24 | p = 2; 25 | for n = 1:bins-7 26 | C = smooth_sign_hist(n:n+7) == cmpFilter; 27 | if sum(C) ==8 28 | index(p) = n+3; 29 | p = p+1; 30 | end 31 | end 32 | index(p) = bins; 33 | factor = zeros([length(index)-1,1]); 34 | span = factor; 35 | M = factor; 36 | range = factor; 37 | start = factor; 38 | endd = factor; 39 | sub_hist = cell([length(index)-1,1]); 40 | for m = 1:length(index)-1; 41 | sub_hist{m} = hist_i(index(m)+1:index(m+1)); 42 | M(m) = sum(sub_hist{m}); 43 | low = mi + index(m); 44 | high = mi + index(m+1)-1; 45 | span(m) = high-low+1; 46 | factor(m) = span(m)*log10(M(m)); 47 | end 48 | factor_sum = sum(factor); 49 | for m = 1:length(index)-1; 50 | range(m) = round((256-mi)*factor(m)/factor_sum); 51 | end 52 | start(1) = mi; 53 | endd(1) = mi+range(1)-1; 54 | for m = 2:length(index)-1; 55 | start(m) = start(m-1)+range(m-1); 56 | endd(m) = endd(m-1)+range(m); 57 | end 58 | y = cell([length(index)-1,1]); 59 | s_r = zeros([1,mi]); 60 | for m = 1:length(index)-1; 61 | hist_cum = cumsum(sub_hist{m}); 62 | c = hist_cum./M(m); 63 | y{m} = round(start(m)+(endd(m)-start(m)).*c); 64 | s_r = [s_r,y{m}]; 65 | end 66 | i_s = zeros(size(i)); 67 | for n = mi:ma 68 | lc = i == n; 69 | i_s(lc) = double(s_r(n+1))/255; 70 | end 71 | % hist_is = hist(double(i_s(:)),bins); 72 | hsi_o = cat(3,h,s,i_s); 73 | d = uint8(hsv2rgb(hsi_o).*255); 74 | -------------------------------------------------------------------------------- /others/colorBalance.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidut/OpenCE/abbc8609b7d5069e20871b585dcf6d18b59f1c0e/others/colorBalance.m -------------------------------------------------------------------------------- /others/dheci.m: -------------------------------------------------------------------------------- 1 | function d = dheci(im,alpha,hist_i,hist_s) 2 | 3 | if ~exist('alpha','var'),alpha = 0.5;end 4 | if ~exist('hist_i','var') || ~exist('hist_s','var'),[hist_i, hist_s] = build_is_hist(im);end 5 | 6 | hsv = rgb2hsv(im); 7 | hist_c = alpha*hist_s+(1-alpha)*hist_i; 8 | hist_sum = sum(hist_c); 9 | hist_cum = cumsum(hist_c); 10 | h = hsv(:,:,1); 11 | s = hsv(:,:,2); 12 | i = uint8(hsv(:,:,3).*255); 13 | c = hist_cum./hist_sum; 14 | s_r = uint8(c.*255); 15 | i_s = zeros(size(i)); 16 | for n = 0:255 17 | lc = i == n; 18 | i_s(lc) = double(s_r(n+1))/255; 19 | end 20 | hsi_o = cat(3,h,s,i_s); 21 | d = uint8(hsv2rgb(hsi_o).*255); 22 | 23 | -------------------------------------------------------------------------------- /others/dong.m: -------------------------------------------------------------------------------- 1 | function d = Dong( im ,w ) 2 | if max(im(:)) > 1 3 | im = im2double(im); 4 | end 5 | isize = size(im); 6 | im = padarray(im,[2*5,2*5,0],'replicate'); 7 | if (~exist('w','var') || w<=0) 8 | w = 0.8; 9 | end 10 | 11 | R = 1 - im; 12 | % [Rd,~] = dehaze(R,w); 13 | Ir = R(:,:,1); 14 | Ig = R(:,:,2); 15 | Ib = R(:,:,3); 16 | 17 | Ir1 = Ir(:); 18 | Ig1 = Ig(:); 19 | Ib1 = Ib(:); 20 | Il = (Ir1+Ig1+Ib1)./3; 21 | n = length(Il); 22 | N = floor(n*0.002); 23 | 24 | Ir_d = ordfilt2(Ir,1,ones(7,7)); 25 | Ig_d = ordfilt2(Ig,1,ones(7,7)); 26 | Ib_d = ordfilt2(Ib,1,ones(7,7)); 27 | darkc = min(min(Ir_d(:),Ig_d(:)),Ib_d(:)); 28 | [~, i] = sort(darkc,1,'descend'); 29 | temp = Il(i(1:N)); 30 | [~,j] = sort(temp,1,'descend'); 31 | Ar = Ir1(i(j(1))); 32 | Ag = Ig1(i(j(1))); 33 | Ab = Ib1(i(j(1))); 34 | % exp(log()) 35 | t = max(1-w.*min(min(Ir_d./Ar,Ig_d./Ag),Ib_d./Ab),10^(-7)); 36 | lc = t<0.5; 37 | t(lc) = 2 * t(lc).^2; 38 | 39 | Sr = (Ir - Ar)./t +Ar; 40 | Sg = (Ig - Ag)./t +Ag; 41 | Sb = (Ib - Ab)./t +Ab; 42 | 43 | Rd = cat(3,Sr,Sg,Sb); 44 | d = 1-Rd(11:isize(1)+10,11:isize(2)+10,:); 45 | end 46 | 47 | -------------------------------------------------------------------------------- /others/he.m: -------------------------------------------------------------------------------- 1 | function image = he(image) 2 | 3 | nChannel = size(image,3); 4 | switch nChannel 5 | case 3 % RGB 6 | image = cat(3, histeq(image(:,:,1)),histeq(image(:,:,2)),histeq(image(:,:,3))); 7 | case 1 % gray 8 | image = histeq(image); 9 | otherwise 10 | for c = 1:nChannel 11 | image(:,:,c) = histeq(image(:,:,c)); 12 | end 13 | end -------------------------------------------------------------------------------- /others/jed.m: -------------------------------------------------------------------------------- 1 | function [I, R, L] = jed(img) 2 | 3 | if ~isfloat(img) 4 | img = im2doule(img) 5 | end 6 | 7 | img = img*255; 8 | 9 | para.alpha = 0.001; 10 | para.beta = 0.007; 11 | para.omega = 0.016; 12 | para.lambda = 6; 13 | 14 | scale = 1; 15 | [I, R, L] = JED.JED(img, para); 16 | % imwrite(I, ['./results/' num2str(i) '_JED.bmp']); 17 | -------------------------------------------------------------------------------- /others/multiscaleRetinex.m: -------------------------------------------------------------------------------- 1 | function OUT = multiscaleRetinex(I, method, varargin) 2 | 3 | if nargin == 0 4 | % I = imload; %imread(imgetfile); %imread('office_1.jpg'); 5 | % J = multiscaleRetinex(I, 'MSRCR'); 6 | % ezFig I J 7 | % return; 8 | 9 | I = imload; %imread(imgetfile); %('office_1.jpg'); 10 | method = Popupmenu({'MSRCR','MSR','SSR'}); 11 | J = ImCtrl(@multiscaleRetinex, I, method); 12 | ezFig I J 13 | end 14 | 15 | if nargin == 1 16 | method = 'MSRCR'; 17 | end 18 | 19 | I = im2double(I).*255+1; % +1 to avoid Inf 20 | SSR = @SSRlog; % @SSR; % 21 | 22 | % TODO: gray or RGB 23 | 24 | switch (method) 25 | case {'SSR' 'single scale retinex'}, f = SSR; 26 | case {'MSR' 'multi scale retinex'}, f = @MSR; 27 | case 'MSRCR', f = @MSRCR; 28 | %case 'MSRCP', f = @MSRCP; 29 | otherwise 30 | return; 31 | %f = str2func(method); 32 | end 33 | 34 | OUT = f(I, varargin{:}); 35 | 36 | end 37 | 38 | function OUT = SSR(I, varargin) 39 | T = imgaussfilt(I, varargin{:}); 40 | OUT = I./(T); % avoid NaN 41 | end 42 | 43 | function OUT = SSRlog(I, varargin) 44 | T = imgaussfilt(I, varargin{:}); 45 | OUT = log(I) - log(T+1) + 0.5; 46 | end 47 | 48 | function OUT = MSR(I, varargin) 49 | if numel(varargin) == 0 50 | varargin = {25 100 240}; 51 | end 52 | OUT = 0; N = numel(varargin); 53 | for n = 1:N 54 | OUT = OUT + (1/N)* multiscaleRetinex(I,'SSR',varargin{n}); 55 | end 56 | end 57 | 58 | function OUT = MSRCR(I, lowScale, medScale, highScale, leftChop, rightChop) 59 | if ~exist('lowScale', 'var'), lowScale = 15; end 60 | if ~exist('MedScale', 'var'), medScale = 80; end 61 | if ~exist('HighScale', 'var'), highScale = 250; end 62 | if ~exist('s1', 'var'), leftChop = 1; end 63 | if ~exist('s2', 'var'), rightChop = 1; end 64 | 65 | MSR = multiscaleRetinex(I, 'MSR', lowScale, medScale, highScale); 66 | 67 | for c = 1:3 68 | CR = (log(125*I(:,:,c))-log(I(:,:,1)+I(:,:,2)+I(:,:,3))); 69 | OUT(:,:,c) = colorBalance(mat2gray(CR.*MSR(:,:,c)), 'simplest', leftChop, rightChop); 70 | end 71 | %OUT = max(0, min(1, OUT)); 72 | end 73 | -------------------------------------------------------------------------------- /others/private/build_is_hist.m: -------------------------------------------------------------------------------- 1 | function [Hist_I, Hist_S] = build_is_hist(im) 2 | [hei wid ch] = size(im); 3 | I = padarray(im,[2,2,0], 'replicate'); 4 | hsv = uint8(rgb2hsv(I).*255); 5 | fh = [-1 0 1;-2 0 2;-1 0 1]; 6 | fv = fh'; 7 | H = hsv(:,:,1); 8 | S = hsv(:,:,2); 9 | I = hsv(:,:,3); 10 | dIh = filter2(fh,I); 11 | dIv = filter2(fv,I); 12 | dI = uint32(sqrt(dIh.^2+dIv.^2)); 13 | di = dI(3:hei+2,3:wid+2); 14 | dSh = filter2(fh,S); 15 | dSv = filter2(fv,S); 16 | dS = uint32(sqrt(dSh.^2+dSv.^2)); 17 | ds = dS(3:hei+2,3:wid+2); 18 | h = H(3:hei+2,3:wid+2); 19 | s = S(3:hei+2,3:wid+2); 20 | i = I(3:hei+2,3:wid+2); 21 | Imean = conv2(double(I),ones(5)/25,'same'); 22 | Smean = conv2(double(S),ones(5)/25,'same'); 23 | Rho = zeros([hei+4 wid+4]); 24 | 25 | for p = 3:hei+2 26 | for q = 3:wid+2 27 | tmpi = double(I(p-2:p+2,q-2:q+2)); 28 | tmps = double(S(p-2:p+2,q-2:q+2)); 29 | corre = corrcoef(tmpi(:),tmps(:)); 30 | Rho(p,q) = corre(1,2); 31 | end 32 | end 33 | 34 | rho = abs(Rho(3:hei+2,3:wid+2)); 35 | rd = uint32(rho.*double(ds)); 36 | Hist_I = zeros(256,1); 37 | Hist_S = zeros(256,1); 38 | 39 | for n = 0:255 40 | lc = i == n; 41 | temp = zeros(size(di)); 42 | temp(lc) = di(lc); 43 | Hist_I(n+1) = sum(temp(:)); 44 | temp = 0; 45 | temp(lc) = rd(lc); 46 | Hist_S(n+1) = sum(temp(:)); 47 | end 48 | -------------------------------------------------------------------------------- /others/private/lowlight_enhancement.p: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidut/OpenCE/abbc8609b7d5069e20871b585dcf6d18b59f1c0e/others/private/lowlight_enhancement.p -------------------------------------------------------------------------------- /others/robustRetinex.m: -------------------------------------------------------------------------------- 1 | %clear; 2 | 3 | 4 | %img = double(imread('9.bmp')); 5 | function res = robustRetinex(img) 6 | 7 | if ~isfloat(img) 8 | img = im2doule(img) 9 | end 10 | 11 | img = img*255; 12 | 13 | para.epsilon_stop_L = 1e-3; 14 | para.epsilon_stop_R = 1e-3; 15 | para.epsilon = 10/255; 16 | para.u = 1; 17 | para.ro = 1.5; 18 | para.lambda = 5; 19 | para.beta = 0.01; 20 | para.omega = 0.01; 21 | para.delta = 10; 22 | 23 | gamma = 2.2; 24 | 25 | [R, L, N] = RobustRetinex.lowlight_enhancement(img, para); 26 | 27 | res = R.*L.^(1/gamma); 28 | 29 | %figure,imshow(res) 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /ours/Ying_2017_CAIP.m: -------------------------------------------------------------------------------- 1 | function fused = Ying_2017_CAIP(I, mu, k, a, b) % camera a, b 2 | %% 3 | % @inproceedings{ying2017new, 4 | % title={A New Image Contrast Enhancement Algorithm Using Exposure Fusion Framework}, 5 | % author={Ying, Zhenqiang and Li, Ge and Ren, Yurui and Wang, Ronggang and Wang, Wenmin}, 6 | % booktitle={International Conference on Computer Analysis of Images and Patterns}, 7 | % pages={36--46}, 8 | % year={2017}, 9 | % organization={Springer} 10 | % } 11 | % 12 | % Please feel free to contact me (yingzhenqiang-at-gmail-dot-com) if you 13 | % have any questions or concerns. 14 | 15 | if ~exist( 'mu', 'var' ) 16 | mu = 0.5; 17 | end 18 | 19 | if ~exist( 'a', 'var' ) 20 | a = -0.3293; 21 | end 22 | 23 | if ~exist( 'b', 'var' ) 24 | b = 1.1258; 25 | end 26 | 27 | if ~isfloat(I) 28 | I = im2double( I ); 29 | end 30 | 31 | lambda = 0.5; 32 | sigma = 5; 33 | 34 | %% t: scene illumination map 35 | t_b = max( I, [], 3 ); % also work for single-channel image 36 | t_our = imresize( tsmooth( imresize( t_b, 0.5 ), lambda, sigma ), size( t_b ) ); 37 | 38 | %% k: exposure ratio 39 | if ~exist( 'k', 'var' ) || isempty(k) 40 | isBad = t_our < 0.5; 41 | J = maxEntropyEnhance(I, isBad); 42 | else 43 | J = applyK(I, k, a, b); %k 44 | J = min(J, 1); % fix overflow 45 | end 46 | 47 | %% W: Weight Matrix 48 | t = repmat(t_our, [1 1 size(I,3)]); 49 | W = t.^mu; 50 | 51 | I2 = I.*W; 52 | J2 = J.*(1-W); 53 | 54 | fused = I2 + J2; 55 | 56 | function J = maxEntropyEnhance(I, isBad) 57 | Y = rgb2gm(real(max(imresize(I, [50 50]), 0))); % max - avoid complex number 58 | 59 | if exist('isBad', 'var') 60 | isBad = (imresize(isBad, [50 50])); 61 | Y = Y(isBad); 62 | end 63 | 64 | if isempty(Y) 65 | J = I; % no enhancement k = 1 66 | return; 67 | end 68 | 69 | opt_k = fminbnd(@(k) ( -entropy(applyK(Y, k)) ),1, 7); 70 | J = applyK(I, opt_k, a, b) - 0.01; 71 | 72 | end 73 | end 74 | 75 | function I = rgb2gm(I) 76 | if size(I,3) == 3 77 | I = im2double(max(0,I)); % negative double --> complex double 78 | I = ( I(:,:,1).*I(:,:,2).*I(:,:,3) ).^(1/3); 79 | end 80 | end 81 | 82 | function J = applyK(I, k, a, b) 83 | 84 | if ~exist( 'a', 'var' ) 85 | a = -0.3293; 86 | end 87 | 88 | if ~exist( 'b', 'var' ) 89 | b = 1.1258; 90 | end 91 | 92 | f = @(x)exp((1-x.^a)*b); 93 | beta = f(k); 94 | gamma = k.^a; 95 | J = I.^gamma.*beta; 96 | end 97 | 98 | function S = tsmooth( I, lambda, sigma, sharpness) 99 | if ( ~exist( 'lambda', 'var' ) ) 100 | lambda = 0.01; 101 | end 102 | if ( ~exist( 'sigma', 'var' ) ) 103 | sigma = 3.0; 104 | end 105 | if ( ~exist( 'sharpness', 'var' ) ) 106 | sharpness = 0.001; 107 | end 108 | I = im2double( I ); 109 | x = I; 110 | [ wx, wy ] = computeTextureWeights( x, sigma, sharpness); 111 | S = solveLinearEquation( I, wx, wy, lambda ); 112 | end 113 | 114 | function [ W_h, W_v ] = computeTextureWeights( fin, sigma, sharpness) 115 | 116 | dt0_v = [diff(fin,1,1);fin(1,:)-fin(end,:)]; 117 | dt0_h = [diff(fin,1,2)';fin(:,1)'-fin(:,end)']'; 118 | 119 | gauker_h = filter2(ones(1,sigma),dt0_h); 120 | gauker_v = filter2(ones(sigma,1),dt0_v); 121 | W_h = 1./(abs(gauker_h).*abs(dt0_h)+sharpness); 122 | W_v = 1./(abs(gauker_v).*abs(dt0_v)+sharpness); 123 | 124 | end 125 | 126 | function OUT = solveLinearEquation( IN, wx, wy, lambda ) 127 | [ r, c, ch ] = size( IN ); 128 | k = r * c; 129 | dx = -lambda * wx( : ); 130 | dy = -lambda * wy( : ); 131 | tempx = [wx(:,end),wx(:,1:end-1)]; 132 | tempy = [wy(end,:);wy(1:end-1,:)]; 133 | dxa = -lambda *tempx(:); 134 | dya = -lambda *tempy(:); 135 | tempx = [wx(:,end),zeros(r,c-1)]; 136 | tempy = [wy(end,:);zeros(r-1,c)]; 137 | dxd1 = -lambda * tempx(:); 138 | dyd1 = -lambda * tempy(:); 139 | wx(:,end) = 0; 140 | wy(end,:) = 0; 141 | dxd2 = -lambda * wx(:); 142 | dyd2 = -lambda * wy(:); 143 | 144 | Ax = spdiags( [dxd1,dxd2], [-k+r,-r], k, k ); 145 | Ay = spdiags( [dyd1,dyd2], [-r+1,-1], k, k ); 146 | 147 | D = 1 - ( dx + dy + dxa + dya); 148 | A = (Ax+Ay) + (Ax+Ay)' + spdiags( D, 0, k, k ); 149 | 150 | if exist( 'ichol', 'builtin' ) 151 | L = ichol( A, struct( 'michol', 'on' ) ); 152 | OUT = IN; 153 | for ii = 1:ch 154 | tin = IN( :, :, ii ); 155 | [ tout, ~ ] = pcg( A, tin( : ), 0.1, 50, L, L' ); 156 | OUT( :, :, ii ) = reshape( tout, r, c ); 157 | end 158 | else 159 | OUT = IN; 160 | for ii = 1:ch 161 | tin = IN( :, :, ii ); 162 | tout = A\tin( : ); 163 | OUT( :, :, ii ) = reshape( tout, r, c ); 164 | end 165 | end 166 | end 167 | 168 | -------------------------------------------------------------------------------- /ours/Ying_2017_ICCV.m: -------------------------------------------------------------------------------- 1 | function J = Ying_2017_ICCV(I, model) 2 | 3 | % @InProceedings{Ying_2017_ICCV, 4 | % author = {Ying, Zhenqiang and Li, Ge and Ren, Yurui and Wang, Ronggang and Wang, Wenmin}, 5 | % title = {A New Low-Light Image Enhancement Algorithm Using Camera Response Model}, 6 | % booktitle = {The IEEE International Conference on Computer Vision (ICCV)}, 7 | % month = {Oct}, 8 | % year = {2017} 9 | % } 10 | % 11 | % Please feel free to contact me (yingzhenqiang-at-gmail-dot-com) if you 12 | % have any questions or concerns. 13 | 14 | if ~isfloat(I), I = im2double(I); end 15 | 16 | %% Param Settings 17 | alpha = 1; 18 | eps = 0.001; 19 | range = 5; 20 | ratioMax = 7; 21 | 22 | %% Camear Model 23 | % we use beta-gamma model as default 24 | if ~exist('model', 'var'), model = 'beta-gamma'; end 25 | 26 | switch lower(model) 27 | case 'preferred' 28 | param = {4.3536 1.2854 0.1447}; 29 | [a, b, c] = deal(param{:}); 30 | g = @(I,k)(I.*(k.^(a.*c)) )./ (( (I).^(1./c) .*(k.^a - 1) + 1).^c); 31 | 32 | case 'beta-gamma' 33 | param = {-0.3293 1.1258}; 34 | [a, b] = deal(param{:}); 35 | f = @(x)exp((1-x.^a).*b); 36 | g = @(I,k)I.^(k.^a).*f(k); 37 | 38 | case 'affine' 39 | param = {-0.1797 1.2076 0.3988}; 40 | [alpha, beta, gamma] = deal(param{:}); 41 | g = @(I,k)I.*(k.^gamma) + alpha.*(1-k.^gamma); 42 | 43 | case 'beta' 44 | c = 0.4800; 45 | g = @(I,k)I.*( k.^c ); 46 | 47 | otherwise 48 | error('unkown model: %s', model); 49 | end 50 | 51 | %% Exposure Ratio Map 52 | 53 | % Initial Exposure Ratio Map 54 | t0 = max(I, [], 3); 55 | [M,N] = size(t0); 56 | 57 | % Exposure Ratio Map Refinement 58 | t0 = imresize(t0,0.5); 59 | dt0_v = [diff(t0,1,1);t0(1,:)-t0(end,:)]; 60 | dt0_h = [diff(t0,1,2)';t0(:,1)'-t0(:,end)']'; 61 | gauker_h = filter2(ones(1,range),dt0_h); 62 | gauker_v = filter2(ones(range,1),dt0_v); 63 | W_h = 1./(abs(gauker_h).*abs(dt0_h)+eps); 64 | W_v = 1./(abs(gauker_v).*abs(dt0_v)+eps); 65 | T = solveLinearEquation(t0,W_h,W_v,alpha./2); 66 | T = imresize(T,[M,N]); 67 | 68 | T = repmat(T, [1 1 3]); 69 | kRatio = min(1./T,ratioMax); 70 | 71 | %% Enhancement 72 | J = g(I, kRatio); 73 | J = max(0, min(1, J)); 74 | 75 | end 76 | 77 | function OUT = solveLinearEquation( IN, wx, wy, lambda ) 78 | [ r, c, ch ] = size( IN ); 79 | k = r * c; 80 | dx = -lambda * wx( : ); 81 | dy = -lambda * wy( : ); 82 | tempx = [wx(:,end),wx(:,1:end-1)]; 83 | tempy = [wy(end,:);wy(1:end-1,:)]; 84 | dxa = -lambda *tempx(:); 85 | dya = -lambda *tempy(:); 86 | tempx = [wx(:,end),zeros(r,c-1)]; 87 | tempy = [wy(end,:);zeros(r-1,c)]; 88 | dxd1 = -lambda * tempx(:); 89 | dyd1 = -lambda * tempy(:); 90 | wx(:,end) = 0; 91 | wy(end,:) = 0; 92 | dxd2 = -lambda * wx(:); 93 | dyd2 = -lambda * wy(:); 94 | 95 | Ax = spdiags( [dxd1,dxd2], [-k+r,-r], k, k ); 96 | Ay = spdiags( [dyd1,dyd2], [-r+1,-1], k, k ); 97 | 98 | D = 1 - ( dx + dy + dxa + dya); 99 | A = (Ax+Ay) + (Ax+Ay)' + spdiags( D, 0, k, k ); 100 | 101 | if exist( 'ichol', 'builtin' ) 102 | L = ichol( A, struct( 'michol', 'on' ) ); 103 | OUT = IN; 104 | for ii = 1:ch 105 | tin = IN( :, :, ii ); 106 | [ tout, flag ] = pcg( A, tin( : ), 0.1, 50, L, L' ); 107 | OUT( :, :, ii ) = reshape( tout, r, c ); 108 | end 109 | else 110 | OUT = IN; 111 | for ii = 1:ch 112 | tin = IN( :, :, ii ); 113 | tout = A\tin( : ); 114 | OUT( :, :, ii ) = reshape( tout, r, c ); 115 | end 116 | end 117 | end -------------------------------------------------------------------------------- /ref.bib: -------------------------------------------------------------------------------- 1 | @inproceedings{fu2016srie, 2 | title={A weighted variational model for simultaneous reflectance and illumination estimation}, 3 | author={Fu, Xueyang and Zeng, Delu and Huang, Yue and Zhang, Xiao-Ping and Ding, Xinghao}, 4 | booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition}, 5 | pages={2782--2790}, 6 | year={2016} 7 | } 8 | @article{celik2011cvc, 9 | title={Contextual and variational contrast enhancement}, 10 | author={Celik, Turgay and Tjahjadi, Tardi}, 11 | journal={IEEE Transactions on Image Processing}, 12 | volume={20}, 13 | number={12}, 14 | pages={3431--3441}, 15 | year={2011}, 16 | publisher={IEEE} 17 | } 18 | @inproceedings{lee2012ldr, 19 | title={Contrast enhancement based on layered difference representation}, 20 | author={Lee, Chulwoo and Lee, Chul and Kim, Chang-Su}, 21 | booktitle={Image Processing (ICIP), 2012 19th IEEE International Conference on}, 22 | pages={965--968}, 23 | year={2012}, 24 | organization={IEEE} 25 | } 26 | @article{arici2009wahe, 27 | title={A histogram modification framework and its application for image contrast enhancement}, 28 | author={Arici, Tarik and Dikbas, Salih and Altunbasak, Yucel}, 29 | journal={IEEE Transactions on image processing}, 30 | volume={18}, 31 | number={9}, 32 | pages={1921--1935}, 33 | year={2009}, 34 | publisher={IEEE} 35 | } 36 | @article{fu2016mf, 37 | title={A fusion-based enhancing method for weakly illuminated images}, 38 | author={Fu, Xueyang and Zeng, Delu and Huang, Yue and Liao, Yinghao and Ding, Xinghao and Paisley, John}, 39 | journal={Signal Processing}, 40 | volume={129}, 41 | pages={82--96}, 42 | year={2016}, 43 | publisher={Elsevier} 44 | } 45 | @article{ibrahim2007bpdhe, 46 | title={Brightness preserving dynamic histogram equalization for image contrast enhancement}, 47 | author={Ibrahim, Haidi and Kong, Nicholas Sia Pik}, 48 | journal={IEEE Transactions on Consumer Electronics}, 49 | volume={53}, 50 | number={4}, 51 | pages={1752--1758}, 52 | year={2007}, 53 | publisher={IEEE} 54 | } 55 | @inproceedings{lee2013amsr, 56 | title={Adaptive multiscale retinex for image contrast enhancement}, 57 | author={Lee, Chang-Hsing and Shih, Jau-Ling and Lien, Cheng-Chang and Han, Chin-Chuan}, 58 | booktitle={Signal-Image Technology \& Internet-Based Systems (SITIS), 2013 International Conference on}, 59 | pages={43--50}, 60 | year={2013}, 61 | organization={IEEE} 62 | } 63 | @inproceedings{dong2011fast, 64 | title={Fast efficient algorithm for enhancement of low lighting video}, 65 | author={Dong, Xuan and Wang, Guan and Pang, Yi and Li, Weixin and Wen, Jiangtao and Meng, Wei and Lu, Yao}, 66 | booktitle={2011 IEEE International Conference on Multimedia and Expo}, 67 | pages={1--6}, 68 | year={2011}, 69 | organization={IEEE} 70 | } 71 | @inproceedings{nakai2013dheci, 72 | title={Color image contrast enhacement method based on differential intensity/saturation gray-levels histograms}, 73 | author={Nakai, Keita and Hoshi, Yoshikatsu and Taguchi, Akira}, 74 | booktitle={Intelligent Signal Processing and Communications Systems (ISPACS), 2013 International Symposium on}, 75 | pages={445--449}, 76 | year={2013}, 77 | organization={IEEE} 78 | } 79 | --------------------------------------------------------------------------------