├── 02_ori.png ├── NUM_demo.m ├── README.md ├── imgs ├── background-extraction.jpg ├── evaluation.jpg ├── fig-2.jpg ├── fig-4.jpg └── smf-mhmf.jpg └── source-code ├── NUM.m └── hmfm_v33.m /02_ori.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datngo93/Nonlinear-Unsharp-Masking/b8912a01dd35ef8f6e5cd817e6558a4926e3f4a1/02_ori.png -------------------------------------------------------------------------------- /NUM_demo.m: -------------------------------------------------------------------------------- 1 | close all; 2 | clear; 3 | clc; 4 | 5 | addpath(genpath('source-code/')); 6 | 7 | img = imread('02_ori.png'); 8 | 9 | figure; 10 | imshow([double(img)/255,NUM(img)]); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nonlinear-Unsharp-Masking 2 | 3 | ## Summary 4 | This source code is a MATLAB implementation of a nonlinear unsharp masking method, published in the proceeding of ICEIC 2020, Barcelona, Spain. The algorithm was implemented by means of generalized operators, therein lies the underlying cause of its robustness against out-of-range issue. 5 | 6 | The block diagram of the proposed algorithm is as follows: 7 | ![Block-Diagram](/imgs/fig-2.jpg) 8 | 9 | The input image ***x*** undergoes the **edge-preserving filtering** step to produce the background signal ***y***, which in turn undergoes the **optional contrast enhancement** step before arriving at the final ***generalized adder***. The detail signal ***d*** is the generalized subtraction of ***y*** from ***x***, and the proposed algorithm adaptively scales it up before adding back to the optinally enhanced ***y***. As a result, the output image ***z*** can exhibit a significant improvement in both contrast and sharpness. 10 | 11 | ## Run the code 12 | Run the file "*NUM_demo.m*" in **MATLAB R2019a** to view the result. The source code is in the *soucre_code* folder, and the detailed explanation of input parameters can be found in the published paper. 13 | 14 | ## Result 15 | ![Background-Extraction](/imgs/background-extraction.jpg) 16 | ![SMF-mHMF](/imgs/smf-mhmf.jpg) 17 | The modified hybrid median filter (mHMF) that constitutes the **edge-preserving filtering** step accelerated the background extraction procedure, as depicted in the figures above. Given the pre-determined threshold, the **edge-preserving filtering** step iteratively applied the mHMF to the input image until the difference between two consecutive results was less than the threshold. Using the mHMF instead of the standard median filter preserved the edges better and converged quicker. 18 | 19 | ![Evaluation](/imgs/evaluation.jpg) 20 | ![One-Line](/imgs/fig-4.jpg) 21 | The evaluation result demonstrated that the proposed algorithm was superior to other benchmark methods and it could effectively overcome the out-of-range issue. 22 | 23 | ## Video demonstration 24 | [![DEMO-1](http://img.youtube.com/vi/ZcA5Hw_zDX4/0.jpg)](http://www.youtube.com/watch?v=ZcA5Hw_zDX4) 25 | [![DEMO-2](http://img.youtube.com/vi/SCsbm0_lP9Y/0.jpg)](http://www.youtube.com/watch?v=SCsbm0_lP9Y) 26 | 27 | ## Reference 28 | In any publication related to the use of the source code, you are kindly requested to cite the following paper: 29 | 30 | D. Ngo, S. Lee and B. Kang, "Nonlinear Unsharp Masking Algorithm," *2020 International Conference on Electronics, Information, and Communication (ICEIC)*, Barcelona, Spain, 2020, pp. 1-6, [doi: 10.1109/ICEIC49074.2020.9051376.](https://ieeexplore.ieee.org/abstract/document/9051376) 31 | -------------------------------------------------------------------------------- /imgs/background-extraction.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datngo93/Nonlinear-Unsharp-Masking/b8912a01dd35ef8f6e5cd817e6558a4926e3f4a1/imgs/background-extraction.jpg -------------------------------------------------------------------------------- /imgs/evaluation.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datngo93/Nonlinear-Unsharp-Masking/b8912a01dd35ef8f6e5cd817e6558a4926e3f4a1/imgs/evaluation.jpg -------------------------------------------------------------------------------- /imgs/fig-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datngo93/Nonlinear-Unsharp-Masking/b8912a01dd35ef8f6e5cd817e6558a4926e3f4a1/imgs/fig-2.jpg -------------------------------------------------------------------------------- /imgs/fig-4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datngo93/Nonlinear-Unsharp-Masking/b8912a01dd35ef8f6e5cd817e6558a4926e3f4a1/imgs/fig-4.jpg -------------------------------------------------------------------------------- /imgs/smf-mhmf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datngo93/Nonlinear-Unsharp-Masking/b8912a01dd35ef8f6e5cd817e6558a4926e3f4a1/imgs/smf-mhmf.jpg -------------------------------------------------------------------------------- /source-code/NUM.m: -------------------------------------------------------------------------------- 1 | %%========================================================================= 2 | % Copyright © 2019, SoC Design Lab., Dong-A University. All Right Reserved. 3 | %========================================================================== 4 | % - Date : 2019/05/21 5 | % - Author : Dat Ngo 6 | % - Affiliation: SoC Design Lab. - Dong-A University 7 | % - Design : Generalized unsharp masking 8 | % Input image must be an integer RGB [0,255] 9 | %========================================================================== 10 | 11 | function [oimgf] = NUM(img,sv,sigma,iterNum,ceEn,gammaMin,gammaMax,n) 12 | 13 | %% Default parameters 14 | switch nargin 15 | case 1 16 | sv = 5; 17 | sigma = 1e-4; 18 | iterNum = 20; 19 | ceEn = false; 20 | gammaMin = 1; 21 | gammaMax = 5; 22 | n = 0.5; 23 | case 2 24 | sigma = 1e-4; 25 | iterNum = 20; 26 | ceEn = false; 27 | gammaMin = 1; 28 | gammaMax = 5; 29 | n = 0.5; 30 | case 3 31 | iterNum = 20; 32 | ceEn = false; 33 | gammaMin = 1; 34 | gammaMax = 5; 35 | n = 0.5; 36 | case 4 37 | ceEn = false; 38 | gammaMin = 1; 39 | gammaMax = 5; 40 | n = 0.5; 41 | case 5 42 | gammaMin = 1; 43 | gammaMax = 5; 44 | n = 0.5; 45 | case 6 46 | gammaMax = 5; 47 | n = 0.5; 48 | case 7 49 | n = 0.5; 50 | otherwise 51 | % all parameters are provided 52 | end 53 | 54 | %=========== Avoid under-shooting =========== 55 | img(img==0) = 1; 56 | img(img==255) = 254; 57 | %============================================ 58 | imgf = double(img)/255; 59 | 60 | %% Unsharp masking 61 | hsv = rgb2hsv(imgf); 62 | x = hsv(:,:,3); 63 | x = 2*x-1; % convert to the [-1,1] domain 64 | 65 | % root signal 66 | yk = x; 67 | H = []; 68 | while iterNum>0 69 | iterNum = iterNum-1; 70 | yk1 = hmfm_v33(yk,sv); 71 | Hnew = mean2(abs(yk1.^2-yk.^2)); 72 | H = cat(1,H,Hnew); 73 | if Hnew