-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Martin
committed
Oct 9, 2022
1 parent
89ddef0
commit c6eacd5
Showing
48 changed files
with
5,184 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,156 @@ | ||
# FMNet | ||
<p align="center"> | ||
<img src="./figures/acmmm.jpg" width="150"> | ||
</p> | ||
|
||
This is the official PyTorch implementation of FMNet in the ACM MM 2022 paper "[FMNet: Frequency-Aware Modulation Network for SDR-to-HDR Translation](https://github.com/MCG-NKU/FMNet.git)". | ||
|
||
# Updates | ||
- 2022.10.09 Init the repositories. | ||
|
||
# Contents | ||
0. [Introduction](#Introduction) | ||
0. [Requirement](#Requirement) | ||
0. [Dataset](#Dataset) | ||
0. [Demo](#Demo) | ||
0. [Train](#Train) | ||
0. [Test](#Test) | ||
0. [Results](#Results) | ||
0. [Citation](#Citation) | ||
0. [Acknowledgment](#Acknowledgment) | ||
0. [Contact](#Contact) | ||
0. [License](#License) | ||
|
||
# Introduction | ||
|
||
High-dynamic-range (HDR) media resources that preserve high contrast and more details in shadow and highlight areas in television are becoming increasingly popular for modern display technology compared to the widely available standard-dynamic-range | ||
(SDR) media resources. However, due to the exorbitant price of HDR cameras, researchers have attempted to develop the SDR-to-HDR techniques to convert the abundant SDR media resources to the HDR versions for cost-saving. Recent SDR-to-HDR meth- | ||
ods mostly apply the image-adaptive modulation scheme to dynamically modulate the local contrast. However, these methods often fail to properly capture the low-frequency cues, resulting in artifacts in the low-frequency regions and low visual quality. | ||
Motivated by the Discrete Cosine Transform (DCT), in this paper, we propose a Frequency-aware Modulation Network (FMNet) to enhance the contrast in a frequency-adaptive way for SDR-to-HDR translation. Specifically, we design a frequency-aware modulation block that can dynamically modulate the features according to its frequency-domain responses. This allows us to reduce the structural distortions and artifacts in the translated low-frequency regions and reconstruct high-quality HDR content in the translated results. Experimental results on the HDRTV1K dataset show that our FMNet outperforms previous methods and the perceptual quality of the generated HDR images can be largely improved. | ||
|
||
<p align="center"> | ||
<img src="./figures/method_pipeline.png" width="1000"> | ||
</p> | ||
|
||
<p align="center"> | ||
<img src="./figures/method_block.png" width="1000"> | ||
</p> | ||
|
||
# Requirement | ||
|
||
1. Python 3.6.10 | ||
|
||
2. NVIDIA GPU | ||
|
||
3. NVIDIA CUDA 10.0.130 | ||
|
||
4. Python Package: | ||
``` | ||
torchvision==0.9.1 | ||
opencv_contrib_python==4.5.1.48 | ||
numpy==1.18.1 | ||
torch==1.8.1 | ||
scipy==1.5.4 | ||
matplotlib==3.3.3 | ||
PyYAML==5.3.1 | ||
tensorboardX==2.2 | ||
``` | ||
|
||
# Dataset | ||
We use the [HDRTV1K](https://github.com/chxy95/HDRTVNet#configuration) dataset for training and evaluation. | ||
You can obtain this dataset from [HDRTVNet](https://github.com/chxy95/HDRTVNet#configuration). | ||
Once you have downloaded the HDRTV1K dataset, you can reorganize the dataset to get a folder with the following structure: | ||
``` | ||
hdrtv1k | ||
├── training_set | ||
| ├── train_hdr | ||
| | └── *.png | ||
| └── train_sdr | ||
| └── *.png | ||
└── test_set | ||
├── test_hdr | ||
| └── *.png | ||
└── test_sdr | ||
└── *.png | ||
``` | ||
You should move this dataset into ```$ROOT/data/``` folder and then prepare the training set through: | ||
``` | ||
cd $ROOT/codes | ||
python preprocessing.py --input_folder ../data/hdrtv1k/training_set/train_sdr --save_folder ../data/hdrtv1k/training_set/train_sdr_sub_c096_s240 --n_thread 20 --crop_sz 96 --step 240 --thres_sz 48 --compression_level 0 | ||
python preprocessing.py --input_folder ../data/hdrtv1k/training_set/train_hdr --save_folder ../data/hdrtv1k/training_set/train_hdr_sub_c096_s240 --n_thread 20 --crop_sz 96 --step 240 --thres_sz 48 --compression_level 0 | ||
``` | ||
|
||
# Demo | ||
### 1. Get pretrained model | ||
Our pretrained model ```fmnet_final.pth``` can be downloaded via [Google Drive](https://drive.google.com/file/d/1VJB8hrHim7BP0V3Q9lw2EjK7sVTEi__9/view?usp=sharing) or [Baidu Netdisk](https://pan.baidu.com/s/1QhCtAbJoG2GwcZ9DiCbQJw) (access code: 5kgw). | ||
Once you have downloaded the pretrained model, please put it into the ```$ROOT/checkpoints``` folder. | ||
|
||
### 2. Inference | ||
You can generate the HDR results through: | ||
``` | ||
cd $ROOT/codes | ||
python inference.py --test_hdr ../data/hdrtv1k/test_set/test_hdr --test_sdr ../data/hdrtv1k/test_set/test_sdr --config ./options/train/fmnet_final.yml --parameter ../checkpoints/fmnet_final.pth | ||
``` | ||
The HDR results will be placed in the ```$ROOT/experiments/fmnet_final/val_images``` folder. | ||
|
||
# Train | ||
### 1. Set up configuration | ||
Our training settings can be found at ```$ROOT/codes/options/train/fmnet_final.yml```. | ||
Please carefully check the hyperparameters inside this config file. | ||
|
||
### 2. Train the FMNet | ||
You can train the FMNet following the configuration in ```$ROOT/codes/options/train/fmnet_final.yml``` through: | ||
``` | ||
cd $ROOT/codes | ||
python train.py -opt options/train/fmnet_final.yml | ||
``` | ||
You can find the saved checkpoints in the folder ```$ROOT/experiments/fmnet_final/models```. | ||
|
||
# Test | ||
You should first download the ```hdr_toolbox``` via [HDR_Toolbox](https://github.com/banterle/HDR_Toolbox) and ```hdrvdp-3.0.6``` via [HDRVDP3](https://sourceforge.net/projects/hdrvdp/files/hdrvdp/3.0.6/), and place these two folder (```hdr_toolbox``` and ```hdrvdp-3.0.6```) into the ```$ROOT\codes``` folder. | ||
Then you can evaluate the performance of FMNet with specific checkpoint ```*.pth``` using the [HDRTV1K](https://github.com/chxy95/HDRTVNet#configuration) dataset: | ||
``` | ||
cd $ROOT/codes | ||
python inference.py --test_hdr ../data/hdrtv1k/test_set/test_hdr --test_sdr ../data/hdrtv1k/test_set/test_sdr --config ./options/train/fmnet_final.yml --parameter ../experiments/fmnet_final/models/*.pth | ||
``` | ||
Once the generated HDR results are placed in ```$ROOT/experiments/fmnet_final/val_images``` folder, you can evaluate the quantitative performance through : | ||
``` | ||
cd $ROOT/codes | ||
python evaluation.py --pd_folder ../experiments/fmnet_final/val_images --gt_folder ../data/hdrtv1k/test_set/test_hdr --norm 65535 | ||
``` | ||
Besides, you can also use Matlab to obtain the HDRVDP3 and SR-SIM scores through ```evaluation.m``` (remember to configure the input arguments in the Matlab file). | ||
|
||
# Results | ||
## Quantitative Results | ||
Quantitative comparison of previous methods and ours on the HDRTV1K dataset: | ||
<p align="center"> | ||
<img src="./figures/table_sota.png" width="1200"> | ||
</p> | ||
|
||
## Visual Results | ||
Qualitative comparison of visual quality by different methods on the HDRTV1K dataset: | ||
<p align="center"> | ||
<img src="./figures/experiment_sota.png" width="1200"> | ||
</p> | ||
|
||
# Citation | ||
If you find the code helpful in your research or work, please cite our paper: | ||
```BibTeX | ||
@InProceedings{xu2022fmnet, | ||
author = {Gang Xu and Qibin Hou and Zhang Le and Ming-Ming Cheng}, | ||
title = {FMNet: Frequency-Aware Modulation Network for SDR-to-HDR Translation}, | ||
booktitle = {Proceedings of the 30th ACM International Conference on Multimedia}, | ||
month = {October}, | ||
year = {2022} | ||
} | ||
``` | ||
|
||
# Acknowledgment | ||
Our code is built on [HDRTVNet](https://github.com/chxy95/HDRTVNet). | ||
We thank the authors for sharing their codes. | ||
|
||
# Contact | ||
If you have any questions, feel free to E-mail me with [[email protected]]([email protected]). | ||
|
||
# License | ||
The code is released under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License for NonCommercial use only. | ||
Any commercial use should get formal permission first. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Ignore everything in this foldr except the .gitignore | ||
|
||
!.gitignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
function linRGB = PQEOTF(E) | ||
|
||
m1 = 0.1593017578125; | ||
m2 = 78.84375; | ||
c1 = 0.8359375; | ||
c2 = 18.8515625; | ||
c3 = 18.6875; | ||
|
||
linRGB = 10000 * ((max((E.^(1/m2))-c1, 0))./(c2-c3*(E.^(1/m2)))).^(1/m1); | ||
linRGB = ClampImg(linRGB, 0, 10000); | ||
|
||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
function output = calculate_hdrvdp3(HQ_img_path, GT_img_path) | ||
|
||
HQ_img = imread(HQ_img_path); | ||
GT_img = imread(GT_img_path); | ||
HQ_img = im2double(HQ_img); | ||
GT_img = im2double(GT_img); | ||
HQ_img = PQEOTF(HQ_img); | ||
GT_img = PQEOTF(GT_img); | ||
|
||
ppd = 50; | ||
res = hdrvdp3('side-by-side', HQ_img, GT_img, 'rgb-bt.2020', ppd, {'rgb_display', 'led-lcd-wcg', 'disable_lowvals_warning', true}); | ||
|
||
output = res.Q; | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
function sim = calculate_srsim(HQ_img_path, GT_img_path) | ||
% ======================================================================== | ||
% SR_SIM Index with automatic downsampling, Version 1.0 | ||
% Copyright(c) 2011 Lin ZHANG | ||
% All Rights Reserved. | ||
% | ||
% ---------------------------------------------------------------------- | ||
% Permission to use, copy, or modify this software and its documentation | ||
% for educational and research purposes only and without fee is hereQ | ||
% granted, provided that this copyright notice and the original authors' | ||
% names appear on all copies and supporting documentation. This program | ||
% shall not be used, rewritten, or adapted as the basis of a commercial | ||
% software or hardware product without first obtaining permission of the | ||
% authors. The authors make no representations about the suitability of | ||
% this software for any purpose. It is provided "as is" without express | ||
% or implied warranty. | ||
%---------------------------------------------------------------------- | ||
% | ||
% This is an implementation of the algorithm for calculating the | ||
% Spectral Residual based Similarity (SR-SIM) index between two images. For | ||
% more details, please refer to our paper: | ||
% Lin Zhang and Hongyu Li, "SR-SIM: A fast and high performance IQA index based on spectral residual", in: Proc. ICIP 2012. | ||
% | ||
%---------------------------------------------------------------------- | ||
% | ||
%Input : (1) image1: the first image being compared | ||
% (2) image2: the second image being compared | ||
% | ||
%Output: sim: the similarity score between two images, a real number | ||
% | ||
%----------------------------------------------------------------------- | ||
|
||
|
||
% image1 = imread('/home/ubuntu/Project/eccv2022/evaluation/result/HDRTVNET_AGCM_LE_HG_HDRTV1K/001.png'); | ||
% image2 = imread('/home/ubuntu/Project/eccv2022/evaluation/result/GT_HDRTV1K/001.png'); | ||
|
||
image1 = imread(HQ_img_path); | ||
image2 = imread(GT_img_path); | ||
|
||
image1 = im2double(image1) * 255; | ||
image2 = im2double(image2) * 255; | ||
|
||
[rows, cols, junk] = size(image1); | ||
if junk == 3 | ||
Y1 = 0.299 * double(image1(:,:,1)) + 0.587 * double(image1(:,:,2)) + 0.114 * double(image1(:,:,3)); | ||
Y2 = 0.299 * double(image2(:,:,1)) + 0.587 * double(image2(:,:,2)) + 0.114 * double(image2(:,:,3)); | ||
else | ||
Y1 = double(image1); | ||
Y2 = double(image2); | ||
end | ||
|
||
%%%%%%%%%%%%%%%%%%%%%%%%% | ||
% Download the image | ||
%%%%%%%%%%%%%%%%%%%%%%%%% | ||
minDimension = min(rows,cols); | ||
F = max(1,round(minDimension / 256)); | ||
aveKernel = fspecial('average',F); | ||
|
||
aveY1 = conv2(Y1, aveKernel,'same'); | ||
aveY2 = conv2(Y2, aveKernel,'same'); | ||
Y1 = aveY1(1:F:rows,1:F:cols); | ||
Y2 = aveY2(1:F:rows,1:F:cols); | ||
|
||
%%%%%%%%%%%%%%%%%%%%%%%%% | ||
% Calculate the visual saliency maps | ||
%%%%%%%%%%%%%%%%%%%%%%%%% | ||
saliencyMap1 = spectralResidueSaliency(Y1); | ||
saliencyMap2 = spectralResidueSaliency(Y2); | ||
%%%%%%%%%%%%%%%%%%%%%%%%% | ||
% Calculate the gradient map | ||
%%%%%%%%%%%%%%%%%%%%%%%%% | ||
dx = [3 0 -3; 10 0 -10; 3 0 -3]/16; | ||
dy = [3 10 3; 0 0 0; -3 -10 -3]/16; | ||
IxY1 = conv2(Y1, dx, 'same'); | ||
IyY1 = conv2(Y1, dy, 'same'); | ||
gradientMap1 = sqrt(IxY1.^2 + IyY1.^2); | ||
|
||
IxY2 = conv2(Y2, dx, 'same'); | ||
IyY2 = conv2(Y2, dy, 'same'); | ||
gradientMap2 = sqrt(IxY2.^2 + IyY2.^2); | ||
|
||
%%%%%%%%%%%%%%%%%%%%%%%%% | ||
% Calculate the SR-SIM | ||
%%%%%%%%%%%%%%%%%%%%%%%%% | ||
C1 = 0.40; %fixed | ||
C2 = 225; | ||
alpha = 0.50;%fixed | ||
|
||
GBVSSimMatrix = (2 * saliencyMap1 .* saliencyMap2 + C1) ./ (saliencyMap1.^2 + saliencyMap2.^2 + C1); | ||
gradientSimMatrix = (2*gradientMap1.*gradientMap2 + C2) ./(gradientMap1.^2 + gradientMap2.^2 + C2); | ||
|
||
weight = max(saliencyMap1, saliencyMap2); | ||
SimMatrix = GBVSSimMatrix .* (gradientSimMatrix .^ alpha) .* weight; | ||
sim = sum(sum(SimMatrix)) / sum(weight(:)); | ||
|
||
return; | ||
|
||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||
function saliencyMap = spectralResidueSaliency(image) | ||
%this function is used to calculate the visual saliency map for the given | ||
%image using the spectral residue method proposed by Xiaodi Hou and Liqing | ||
%Zhang. For more details about this method, you can refer to the paper: | ||
%Saliency detection: a spectral residual approach. | ||
|
||
%there are some parameters needed to be adjusted | ||
scale = 0.25; %fixed | ||
aveKernelSize = 3; %fixed | ||
gauSigma = 3.8; %fixed | ||
gauSize = 10; %fixed | ||
|
||
inImg = imresize(image, scale); | ||
|
||
%%%% Spectral Residual | ||
myFFT = fft2(inImg); | ||
myLogAmplitude = log(abs(myFFT)); | ||
myPhase = angle(myFFT); | ||
|
||
mySpectralResidual = myLogAmplitude - imfilter(myLogAmplitude, fspecial('average', aveKernelSize), 'replicate'); | ||
saliencyMap = abs(ifft2(exp(mySpectralResidual + 1i*myPhase))).^2; | ||
|
||
%%%% After Effect | ||
saliencyMap = mat2gray(imfilter(saliencyMap, fspecial('gaussian', [gauSize, gauSize], gauSigma))); | ||
saliencyMap = imresize(saliencyMap,[size(image,1) size(image,2)]); |
Oops, something went wrong.