From 583875c77f55949c4d3ee5045a4045d72bde4c10 Mon Sep 17 00:00:00 2001 From: pandersson94 Date: Wed, 16 Oct 2024 17:33:29 +0200 Subject: [PATCH 01/32] Minor fix in python/flip/main.cpp --- python/flip/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/flip/main.cpp b/python/flip/main.cpp index f4df95a..11df041 100644 --- a/python/flip/main.cpp +++ b/python/flip/main.cpp @@ -286,8 +286,8 @@ int execute(const py::list argvPy) // Setup the pybind11 module. PYBIND11_MODULE(pbflip, handle) { - handle.doc() = "Load images (load), evaluate FLIP (evaluate), or run the full FLIP tool (run_tool)."; + handle.doc() = "Load images (load), evaluate FLIP (evaluate), or run the full FLIP tool (execute)."; handle.def("evaluate", &evaluate); handle.def("load", &load); handle.def("execute", &execute); -} \ No newline at end of file +} From c9d0dd1b2c5b626c69b16b6615d7d7f2dec92755 Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Wed, 30 Oct 2024 11:43:27 +0100 Subject: [PATCH 02/32] Update to FLIP v1.5. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Flipped the ꟻ in ꟻLIP. The entire name (FLIP) should now be readable on all devices. - Published Python version of FLIP to PyPI (URL: ?). - The distribution has been tested on Windows, Linux (Ubuntu), and macOS. - The Python version of FLIP (tool and API) is now installed by `pip install flip-evaluator`. - After installation, the tool can be run directly in a shell by `flip --reference reference.{png|exr} --test test.{png|exr}`. - After installation, the FLIP API is available in Python by `import flip_evaluator as flip`. - Directory structure in the FLIP repository has been altered to accomodate the Python version being published to PyPI. - Updated Python/C++/CUDA test script. - Various bugfixes. --- .gitignore | 4 +- LICENSE | 31 ++++++++ README.md | 67 +++++++++--------- .../CMakeLists.txt | 0 {python/flip => flip_evaluator}/__init__.py | 2 +- .../cmake}/FLIPConfig.cmake | 0 {cpp => flip_evaluator/cpp}/CMakeLists.txt | 0 {cpp => flip_evaluator/cpp}/FLIP.h | 40 +++++------ {cpp => flip_evaluator/cpp}/FLIP.sln | 0 {cpp => flip_evaluator/cpp}/README.md | 42 +++++------ .../cpp}/tool/CMakeLists.txt | 0 {cpp => flip_evaluator/cpp}/tool/CPP.vcxproj | 0 .../cpp}/tool/CPP.vcxproj.filters | 0 {cpp => flip_evaluator/cpp}/tool/CUDA.vcxproj | 0 .../cpp}/tool/CUDA.vcxproj.filters | 0 .../cpp}/tool/FLIP-tool.cpp | 0 {cpp => flip_evaluator/cpp}/tool/FLIP-tool.cu | 0 .../cpp}/tool/FLIPToolHelpers.h | 47 ++++++------ .../cpp}/tool/commandline.h | 2 +- {cpp => flip_evaluator/cpp}/tool/filename.h | 9 +-- .../cpp}/tool/imagehelpers.h | 0 {cpp => flip_evaluator/cpp}/tool/pooling.h | 1 - {cpp => flip_evaluator/cpp}/tool/stb_image.h | 0 .../cpp}/tool/stb_image_write.h | 0 {cpp => flip_evaluator/cpp}/tool/tinyexr.h | 0 .../flip_python_api.py | 16 ++--- .../images}/reference.exr | Bin .../images}/reference.png | Bin {images => flip_evaluator/images}/teaser.png | Bin {images => flip_evaluator/images}/test.exr | Bin {images => flip_evaluator/images}/test.png | Bin {misc => flip_evaluator/misc}/CLA.md | 0 {misc => flip_evaluator/misc}/FLIP.txt | 0 {misc => flip_evaluator/misc}/HDRFLIP.txt | 0 {misc => flip_evaluator/misc}/LDRFLIP.txt | 0 .../misc}/LICENSE-third-party.md | 0 .../misc}/papersUsingFLIP.md | 11 ++- {misc => flip_evaluator/misc}/precision.md | 2 +- .../misc}/separatedConvolutions.pdf | Bin {misc => flip_evaluator/misc}/versionList.md | 27 ++++--- .../main.cpp => flip_evaluator/pybindFLIP.cpp | 36 ++++------ {python => flip_evaluator/python}/README.md | 59 ++++++++------- .../python}/api_example.py | 2 +- {pytorch => flip_evaluator/pytorch}/README.md | 26 +++---- {pytorch => flip_evaluator/pytorch}/data.py | 0 .../pytorch}/flip_loss.py | 0 {pytorch => flip_evaluator/pytorch}/train.py | 0 .../tests}/correct_hdrflip_cpp.png | Bin .../tests}/correct_hdrflip_cuda.png | Bin .../tests}/correct_ldrflip_cpp.png | Bin .../tests}/correct_ldrflip_cuda.png | Bin {tests => flip_evaluator/tests}/test.py | 55 ++++++++------ .../tests}/test_pytorch.py | 0 misc/LICENSE.md | 28 -------- python/pyproject.toml => pyproject.toml | 4 +- python/flip.py | 39 ---------- python/requirements.txt | 2 - python/setup.py => setup.py | 21 ++++-- 58 files changed, 272 insertions(+), 301 deletions(-) create mode 100644 LICENSE rename CMakeLists.txt => flip_evaluator/CMakeLists.txt (100%) rename {python/flip => flip_evaluator}/__init__.py (97%) rename {cmake => flip_evaluator/cmake}/FLIPConfig.cmake (100%) rename {cpp => flip_evaluator/cpp}/CMakeLists.txt (100%) rename {cpp => flip_evaluator/cpp}/FLIP.h (98%) rename {cpp => flip_evaluator/cpp}/FLIP.sln (100%) rename {cpp => flip_evaluator/cpp}/README.md (76%) rename {cpp => flip_evaluator/cpp}/tool/CMakeLists.txt (100%) rename {cpp => flip_evaluator/cpp}/tool/CPP.vcxproj (100%) rename {cpp => flip_evaluator/cpp}/tool/CPP.vcxproj.filters (100%) rename {cpp => flip_evaluator/cpp}/tool/CUDA.vcxproj (100%) rename {cpp => flip_evaluator/cpp}/tool/CUDA.vcxproj.filters (100%) rename {cpp => flip_evaluator/cpp}/tool/FLIP-tool.cpp (100%) rename {cpp => flip_evaluator/cpp}/tool/FLIP-tool.cu (100%) rename {cpp => flip_evaluator/cpp}/tool/FLIPToolHelpers.h (94%) rename {cpp => flip_evaluator/cpp}/tool/commandline.h (99%) rename {cpp => flip_evaluator/cpp}/tool/filename.h (98%) rename {cpp => flip_evaluator/cpp}/tool/imagehelpers.h (100%) rename {cpp => flip_evaluator/cpp}/tool/pooling.h (99%) rename {cpp => flip_evaluator/cpp}/tool/stb_image.h (100%) rename {cpp => flip_evaluator/cpp}/tool/stb_image_write.h (100%) rename {cpp => flip_evaluator/cpp}/tool/tinyexr.h (100%) rename python/flip/main.py => flip_evaluator/flip_python_api.py (96%) rename {images => flip_evaluator/images}/reference.exr (100%) rename {images => flip_evaluator/images}/reference.png (100%) rename {images => flip_evaluator/images}/teaser.png (100%) rename {images => flip_evaluator/images}/test.exr (100%) rename {images => flip_evaluator/images}/test.png (100%) rename {misc => flip_evaluator/misc}/CLA.md (100%) rename {misc => flip_evaluator/misc}/FLIP.txt (100%) rename {misc => flip_evaluator/misc}/HDRFLIP.txt (100%) rename {misc => flip_evaluator/misc}/LDRFLIP.txt (100%) rename {misc => flip_evaluator/misc}/LICENSE-third-party.md (100%) rename {misc => flip_evaluator/misc}/papersUsingFLIP.md (99%) rename {misc => flip_evaluator/misc}/precision.md (93%) rename {misc => flip_evaluator/misc}/separatedConvolutions.pdf (100%) rename {misc => flip_evaluator/misc}/versionList.md (73%) rename python/flip/main.cpp => flip_evaluator/pybindFLIP.cpp (92%) rename {python => flip_evaluator/python}/README.md (55%) rename {python => flip_evaluator/python}/api_example.py (99%) rename {pytorch => flip_evaluator/pytorch}/README.md (72%) rename {pytorch => flip_evaluator/pytorch}/data.py (100%) rename {pytorch => flip_evaluator/pytorch}/flip_loss.py (100%) rename {pytorch => flip_evaluator/pytorch}/train.py (100%) rename {tests => flip_evaluator/tests}/correct_hdrflip_cpp.png (100%) rename {tests => flip_evaluator/tests}/correct_hdrflip_cuda.png (100%) rename {tests => flip_evaluator/tests}/correct_ldrflip_cpp.png (100%) rename {tests => flip_evaluator/tests}/correct_ldrflip_cuda.png (100%) rename {tests => flip_evaluator/tests}/test.py (78%) rename {tests => flip_evaluator/tests}/test_pytorch.py (100%) delete mode 100644 misc/LICENSE.md rename python/pyproject.toml => pyproject.toml (96%) delete mode 100644 python/flip.py delete mode 100644 python/requirements.txt rename python/setup.py => setup.py (83%) diff --git a/.gitignore b/.gitignore index 10477af..b0f8112 100644 --- a/.gitignore +++ b/.gitignore @@ -32,8 +32,8 @@ _ReSharper*/ # Python ignores *__pycache__* -python/build/ -python/*.egg-info/ +dist/ +*.egg-info/ # LaTeX ignores *.synctex.gz diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1590055 --- /dev/null +++ b/LICENSE @@ -0,0 +1,31 @@ +BSD 3-Clause License + +Copyright (c) 2020-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +SPDX-FileCopyrightText: Copyright (c) 2020-2024 NVIDIA CORPORATION & AFFILIATES +SPDX-License-Identifier: BSD-3-Clause \ No newline at end of file diff --git a/README.md b/README.md index 30f9c9a..a64c1f6 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -![Teaser image](images/teaser.png "Teaser image") +![Teaser image](flip_evaluator/images/teaser.png "Teaser image") -# ꟻLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.4) +# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.5) By -[Pontus Ebelin](https://research.nvidia.com/person/pontus-ebelin), +[Pontus Ebelin](https://research.nvidia.com/person/pontus-ebelin) and [Tomas Akenine-Möller](https://research.nvidia.com/person/tomas-akenine-m%C3%B6ller), with @@ -14,57 +14,58 @@ Jim Nilsson, and [Peter Shirley](https://research.nvidia.com/person/peter-shirley). -This repository holds implementations of the [LDR-ꟻLIP](https://research.nvidia.com/publication/2020-07_FLIP) -and [HDR-ꟻLIP](https://research.nvidia.com/publication/2021-05_HDR-FLIP) image error metrics. -It also holds code for the ꟻLIP tool, presented in [Ray Tracing Gems II](https://www.realtimerendering.com/raytracinggems/rtg2/index.html). +This repository holds implementations of the [LDR-FLIP](https://research.nvidia.com/publication/2020-07_FLIP) +and [HDR-FLIP](https://research.nvidia.com/publication/2021-05_HDR-FLIP) image error metrics. +It also holds code for the FLIP tool, presented in [Ray Tracing Gems II](https://www.realtimerendering.com/raytracinggems/rtg2/index.html). -The changes made for the different versions of ꟻLIP are summarized in the [version list](misc/versionList.md). +The changes made for the different versions of FLIP are summarized in the [version list](misc/versionList.md). -[A list of papers](misc/papersUsingFLIP.md) that use/cite ꟻLIP. +[A list of papers](flip_evaluator/misc/papersUsingFLIP.md) that use/cite FLIP. -[A note](misc/precision.md) about the precision of ꟻLIP. +[A note](flip_evaluator/misc/precision.md) about the precision of FLIP. [An image gallery](https://research.nvidia.com/node/3525) displaying a large quantity of reference/test images and corresponding error maps from different metrics. -**Note**: in v1.3, we switched to a *single header* ([FLIP.h](https://github.com/NVlabs/flip/blob/singleheader_WIP/cpp/FLIP.h)) for C++/CUDA for easier integration. +**Note**: since v1.5, the Python version of FLIP can now be installed via `pip install flip-evaluator`. + +**Note**: in v1.3, we switched to a *single header* ([FLIP.h](flip_evaluator/cpp/FLIP.h)) for C++/CUDA for easier integration. # License Copyright © 2020-2024, NVIDIA Corporation & Affiliates. All rights reserved. -This work is made available under a [BSD 3-Clause License](misc/LICENSE.md). +This work is made available under a [BSD 3-Clause License](LICENSE). -The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](misc/LICENSE-third-party.md#bsd-3-clause-license),
-and `stb_image`, which is subject to an [MIT License](misc/LICENSE-third-party.md#mit-license). +The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](flip_evaluator/misc/LICENSE-third-party.md#bsd-3-clause-license),
+and `stb_image`, which is subject to an [MIT License](flip_evaluator/misc/LICENSE-third-party.md#mit-license). -For individual contributions to the project, please confer the [Individual Contributor License Agreement](misc/CLA.md). +For individual contributions to the project, please confer the [Individual Contributor License Agreement](flip_evaluator/misc/CLA.md). For business inquiries, please visit our website and submit the form: [NVIDIA Research Licensing](https://www.nvidia.com/en-us/research/inquiries/). # Python (API and Tool) **Setup** (with pip): ``` -cd python -pip install -r requirements.txt . +pip install flip-evaluator ``` **Usage:**
API:
-See the example script `python/api_example.py`. Note that the script requires `matplotlib`. +See the example script `flip_evaluator/python/api_example.py`.. Tool: ``` -python flip.py --reference reference.{exr|png} --test test.{exr|png} [--options] +flip --reference reference.{exr|png} --test test.{exr|png} [--options] ``` -See the [README](python/README.md) in the `python` folder and run `python flip.py -h` for further information and usage instructions. +See the [README](flip_evaluator/python/README.md) in the `python` folder and run `flip -h` for further information and usage instructions. # C++ and CUDA (API and Tool) **Setup:** -The `FLIP.sln` solution contains one CUDA backend project and one pure C++ backend project. +The `flip_evaluator/cpp/FLIP.sln` solution contains one CUDA backend project and one pure C++ backend project. Compiling the CUDA project requires a CUDA compatible GPU. Instruction on how to install CUDA can be found [here](https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/index.html). @@ -84,17 +85,17 @@ CUDA support is enabled via the `FLIP_ENABLE_CUDA`, which can be passed to CMake **Usage:**
API:
-See the [README](cpp/README.md). +See the [README](flip_evaluator/cpp/README.md). Tool: ``` flip[-cuda].exe --reference reference.{exr|png} --test test.{exr|png} [options] ``` -See the [README](cpp/README.md) in the `cpp` folder and run `flip[-cuda].exe -h` for further information and usage instructions. +See the [README](flip_evaluator/cpp/README.md) in the `flip_evaluator/cpp` folder and run `flip[-cuda].exe -h` for further information and usage instructions. # PyTorch (Loss Function) -**Setup** (with Anaconda3): +**Setup** (with Anaconda3 or Miniconda): ``` conda create -n flip_dl python numpy matplotlib conda activate flip_dl @@ -106,21 +107,21 @@ conda install -c conda-forge openexr-python *Remember to activate the* `flip_dl` *environment through* `conda activate flip_dl` *before using the loss function.* -LDR- and HDR-ꟻLIP are implemented as loss modules in `flip_loss.py`. An example where the loss function is used to train a simple autoencoder is provided in `train.py`. +LDR- and HDR-FLIP are implemented as loss modules in `flip_evaluator/pytorch/flip_loss.py`. An example where the loss function is used to train a simple autoencoder is provided in `flip_evaluator/pytorch/train.py`. -See the [README](pytorch/README.md) in the `pytorch` folder for further information and usage instructions. +See the [README](flip_evaluator/pytorch/README.md) in the `pytorch` folder for further information and usage instructions. # Citation -If your work uses the ꟻLIP tool to find the errors between *low dynamic range* images, -please cite the LDR-ꟻLIP paper:
-[Paper](https://research.nvidia.com/publication/2020-07_FLIP) | [BibTeX](misc/LDRFLIP.txt) +If your work uses the FLIP tool to find the errors between *low dynamic range* images, +please cite the LDR-FLIP paper:
+[Paper](https://research.nvidia.com/publication/2020-07_FLIP) | [BibTeX](flip_evaluator/misc/LDRFLIP.txt) -If it uses the ꟻLIP tool to find the errors between *high dynamic range* images, -instead cite the HDR-ꟻLIP paper:
-[Paper](https://research.nvidia.com/publication/2021-05_HDR-FLIP) | [BibTeX](misc/HDRFLIP.txt) +If it uses the FLIP tool to find the errors between *high dynamic range* images, +instead cite the HDR-FLIP paper:
+[Paper](https://research.nvidia.com/publication/2021-05_HDR-FLIP) | [BibTeX](flip_evaluator/misc/HDRFLIP.txt) -Should your work use the ꟻLIP tool in a more general fashion, please cite the Ray Tracing Gems II article:
-[Chapter](https://link.springer.com/chapter/10.1007%2F978-1-4842-7185-8_19) | [BibTeX](misc/FLIP.txt) +Should your work use the FLIP tool in a more general fashion, please cite the Ray Tracing Gems II article:
+[Chapter](https://link.springer.com/chapter/10.1007%2F978-1-4842-7185-8_19) | [BibTeX](flip_evaluator/misc/FLIP.txt) # Acknowledgements We appreciate the following peoples' contributions to this repository: diff --git a/CMakeLists.txt b/flip_evaluator/CMakeLists.txt similarity index 100% rename from CMakeLists.txt rename to flip_evaluator/CMakeLists.txt diff --git a/python/flip/__init__.py b/flip_evaluator/__init__.py similarity index 97% rename from python/flip/__init__.py rename to flip_evaluator/__init__.py index 22745d2..ae18cc7 100644 --- a/python/flip/__init__.py +++ b/flip_evaluator/__init__.py @@ -30,4 +30,4 @@ # SPDX-License-Identifier: BSD-3-Clause ################################################################################# -from .main import evaluate, execute, load \ No newline at end of file +from .flip_python_api import evaluate, load \ No newline at end of file diff --git a/cmake/FLIPConfig.cmake b/flip_evaluator/cmake/FLIPConfig.cmake similarity index 100% rename from cmake/FLIPConfig.cmake rename to flip_evaluator/cmake/FLIPConfig.cmake diff --git a/cpp/CMakeLists.txt b/flip_evaluator/cpp/CMakeLists.txt similarity index 100% rename from cpp/CMakeLists.txt rename to flip_evaluator/cpp/CMakeLists.txt diff --git a/cpp/FLIP.h b/flip_evaluator/cpp/FLIP.h similarity index 98% rename from cpp/FLIP.h rename to flip_evaluator/cpp/FLIP.h index c700032..a27cdc9 100644 --- a/cpp/FLIP.h +++ b/flip_evaluator/cpp/FLIP.h @@ -52,8 +52,8 @@ // // 1. FLIP::evaluate(const bool useHDR, FLIP::Parameters& parameters, FLIP::image& referenceImageInput, FLIP::image& testImageInput, // FLIP::image& errorMapFLIPOutput, FLIP::image& maxErrorExposureMapOutput, -// const bool returnLDRFLIPImages, std::vector*>& hdrOutputFlipLDRImages, -// const bool returnLDRImages, std::vector*>& hdrOutputLDRImages) +// const bool returnIntermediateLDRFLIPImages, std::vector*>& intermediateLDRFLIPImages, +// const bool returnIntermediateLDRImages, std::vector*>& intermediateLDRImages) // // # This is the one with most parameters and is used by FLIP-tool.cpp in main(). // # See the function at the bottom of this file for detailed description of the parameters. @@ -1137,7 +1137,7 @@ namespace FLIP this->init({ size, 1, 1 }); if (this->mvpHostData != nullptr) { - memcpy(this->mvpHostData, pColorMap, size * sizeof(color3)); + memcpy((void*) this->mvpHostData, pColorMap, size * sizeof(color3)); } } #else // FLIP_ENABLE_CUDA @@ -1235,7 +1235,7 @@ namespace FLIP void setPixels(const float* pPixels, const int width, const int height) { this->init({ width, height, 1 }); - memcpy(this->mvpHostData, pPixels, size_t(width) * height * sizeof(T)); + memcpy((void*) this->mvpHostData, pPixels, size_t(width) * height * sizeof(T)); } #else T get(int x, int y, int z) @@ -1262,7 +1262,7 @@ namespace FLIP { this->init({ width, height, 1}); } - memcpy(this->mvpHostData, pPixels, size_t(width) * height * sizeof(T)); + memcpy((void*) this->mvpHostData, pPixels, size_t(width) * height * sizeof(T)); this->mState = CudaTensorState::HOST_ONLY; } #endif @@ -1439,7 +1439,7 @@ namespace FLIP { if (this->mDim.x == srcImage.getWidth() && this->mDim.y == srcImage.getHeight() && this->mDim.z == srcImage.getDepth()) { - memcpy(this->mvpHostData, srcImage.getHostData(), this->mVolume * sizeof(T)); + memcpy((void*) this->mvpHostData, srcImage.getHostData(), this->mVolume * sizeof(T)); } } @@ -2321,16 +2321,16 @@ namespace FLIP * @param[out] errorMapFLIPOutput The FLIP error image in [0,1], a single channel (grayscale). The user should map it using MapMagma if that is desired (with: errorMapWithMagma.colorMap(errorMapFLIP, FLIP::magmaMap);) * @param[out] maxErrorExposureMapOutput Exposure map output (only for HDR content). - * @param[in] returnLDRFLIPImages True if the next argument should be filled in by FLIP::evaluate(). - * @param[out] hdrOutputFlipLDRImages A list of temporary output LDR-FLIP error maps (in grayscale) from HDR-FLIP. + * @param[in] returnIntermediateLDRFLIPImages True if the next argument should be filled in by FLIP::evaluate(). + * @param[out] intermediateLDRFLIPImages A list of temporary output LDR-FLIP error maps (in grayscale) from HDR-FLIP. See explanation of the errorMapFLIPOutput parameter for how to convert the maps to magma. - * @param[in] returnLDRImages True if the next argument should be filled in by FLIP::evaluate(). - * @param[out] hdrOutputLDRImages A list of temporary tonemapped output LDR images (in linear RGB) from HDR-FLIP. Images in this order: Ref0, Test0, Ref1, Test1,... + * @param[in] returnIntermediateLDRImages True if the next argument should be filled in by FLIP::evaluate(). + * @param[out] intermediateLDRImages A list of temporary tonemapped output LDR images (in linear RGB) from HDR-FLIP. Images in this order: Ref0, Test0, Ref1, Test1,... */ static void evaluate(FLIP::image& referenceImageInput, FLIP::image& testImageInput, const bool useHDR, FLIP::Parameters& parameters, FLIP::image& errorMapFLIPOutput, FLIP::image& maxErrorExposureMapOutput, - const bool returnLDRFLIPImages, std::vector*>& hdrOutputFlipLDRImages, - const bool returnLDRImages, std::vector*>& hdrOutputLDRImages) + const bool returnIntermediateLDRFLIPImages, std::vector*>& intermediateLDRFLIPImages, + const bool returnIntermediateLDRImages, std::vector*>& intermediateLDRImages) { FLIP::image referenceImage(referenceImageInput.getWidth(), referenceImageInput.getHeight()); FLIP::image testImage(referenceImageInput.getWidth(), referenceImageInput.getHeight()); @@ -2383,15 +2383,15 @@ namespace FLIP tImage.toneMap(parameters.tonemapper); rImage.clamp(); tImage.clamp(); - if (returnLDRImages) + if (returnIntermediateLDRImages) { - hdrOutputLDRImages.push_back(new FLIP::image(rImage)); - hdrOutputLDRImages.push_back(new FLIP::image(tImage)); + intermediateLDRImages.push_back(new FLIP::image(rImage)); + intermediateLDRImages.push_back(new FLIP::image(tImage)); } tmpErrorMap.LDR_FLIP(rImage, tImage, parameters.PPD); - if (returnLDRFLIPImages) + if (returnIntermediateLDRFLIPImages) { - hdrOutputFlipLDRImages.push_back(new FLIP::image(tmpErrorMap)); + intermediateLDRFLIPImages.push_back(new FLIP::image(tmpErrorMap)); } errorMapFLIPOutput.setMaxExposure(tmpErrorMap, maxErrorExposureMapOutput, float(i) / (parameters.numExposures - 1)); } @@ -2408,9 +2408,9 @@ namespace FLIP static void evaluate(FLIP::image& referenceImageInput, FLIP::image& testImageInput, const bool useHDR, FLIP::Parameters& parameters, FLIP::image& errorMapFLIPOutput, FLIP::image& maxErrorExposureMapOutput) { - std::vector*> hdrOutputFlipLDRImages; - std::vector*> hdrOutputLDRImages; - FLIP::evaluate(referenceImageInput, testImageInput, useHDR, parameters, errorMapFLIPOutput, maxErrorExposureMapOutput, false, hdrOutputFlipLDRImages, false, hdrOutputLDRImages); + std::vector*> intermediateLDRFLIPImages; + std::vector*> intermediateLDRImages; + FLIP::evaluate(referenceImageInput, testImageInput, useHDR, parameters, errorMapFLIPOutput, maxErrorExposureMapOutput, false, intermediateLDRFLIPImages, false, intermediateLDRImages); } // This variant does not return the exposure map, which may also be used quite seldom. diff --git a/cpp/FLIP.sln b/flip_evaluator/cpp/FLIP.sln similarity index 100% rename from cpp/FLIP.sln rename to flip_evaluator/cpp/FLIP.sln diff --git a/cpp/README.md b/flip_evaluator/cpp/README.md similarity index 76% rename from cpp/README.md rename to flip_evaluator/cpp/README.md index 6419130..02b4876 100644 --- a/cpp/README.md +++ b/flip_evaluator/cpp/README.md @@ -1,7 +1,7 @@ -# ꟻLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.4) +# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.5) By -[Pontus Ebelin](https://research.nvidia.com/person/pontus-ebelin), +[Pontus Ebelin](https://research.nvidia.com/person/pontus-ebelin) and [Tomas Akenine-Möller](https://research.nvidia.com/person/tomas-akenine-m%C3%B6ller), with @@ -12,11 +12,11 @@ Jim Nilsson, and [Peter Shirley](https://research.nvidia.com/person/peter-shirley). -This [repository](https://github.com/NVlabs/flip) holds implementations of the [LDR-ꟻLIP](https://research.nvidia.com/publication/2020-07_FLIP) -and [HDR-ꟻLIP](https://research.nvidia.com/publication/2021-05_HDR-FLIP) image error metrics in C++ and CUDA. -It also holds code for the ꟻLIP tool, presented in [Ray Tracing Gems II](https://www.realtimerendering.com/raytracinggems/rtg2/index.html). +This [repository](https://github.com/NVlabs/flip) holds implementations of the [LDR-FLIP](https://research.nvidia.com/publication/2020-07_FLIP) +and [HDR-FLIP](https://research.nvidia.com/publication/2021-05_HDR-FLIP) image error metrics in C++ and CUDA. +It also holds code for the FLIP tool, presented in [Ray Tracing Gems II](https://www.realtimerendering.com/raytracinggems/rtg2/index.html). -Note that since v1.2, we use separated convolutions for the C++ and CUDA versions of ꟻLIP. A note explaining those +Note that since v1.2, we use separated convolutions for the C++ and CUDA versions of FLIP. A note explaining those can be found [here](misc/separatedConvolutions.pdf). With v1.3, we have switched to a single header [FLIP.h](FLIP.h) for easier integration into other projects. @@ -28,7 +28,7 @@ Since v1.4, the majority of the code for the tool is contained in [FLIPToolHelpe Copyright © 2020-2024, NVIDIA Corporation & Affiliates. All rights reserved. -This work is made available under a [BSD 3-Clause License](../misc/LICENSE.md). +This work is made available under a [BSD 3-Clause License](../../LICENSE). The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](../misc/LICENSE-third-party.md#bsd-3-clause-license),
and `stb_image`, which is subject to an [MIT License](../misc/LICENSE-third-party.md#mit-license). @@ -63,28 +63,28 @@ For business inquiries, please visit our website and submit the form: [NVIDIA Re `FLIP_LIBRARY` option allows to output a library rather than an executable. - Usage: `flip[-cuda].exe --reference reference.{exr|png} --test test.{exr|png} [options]`, where the list of options can be seen by `flip[-cuda].exe -h`. - Tested on Windows 10 version 22H2 and Windows 11 version 23H2 with CUDA 12.3. Compiled with Visual Studio 2022. If you use another version of CUDA, you will need to change the `CUDA 12.3` strings in the `CUDA.vcxproj` file accordingly. -- `../tests/test.py` contains simple tests used to test whether code updates alter results. -- Weighted histograms are output as Python scripts. Running the script will create a PDF version of the histogram. Notice that those scripts require `numpy` and `matplotlib`, both of which may be installed using pip. These are automantically installed when installing the Python version of ꟻLIP (see [README.md](https://github.com/NVlabs/flip/blob/main/python/README.md)). -- The naming convention used for the ꟻLIP tool's output is as follows (where `ppd` is the assumed number of pixels per degree, - `tm` is the tone mapper assumed by HDR-ꟻLIP, `cstart` and `cstop` are the shortest and longest exposures, respectively, assumed by HDR-ꟻLIP, +- `flip_evaluator/tests/test.py` contains simple tests used to test whether code updates alter results. +- Weighted histograms are output as Python scripts. Running the script will create a PDF version of the histogram. Notice that those scripts require `numpy` and `matplotlib`, both of which may be installed using pip. These are automantically installed when installing the Python version of FLIP (see [README.md](../python/README.md)). +- The naming convention used for the FLIP tool's output is as follows (where `ppd` is the assumed number of pixels per degree, + `tm` is the tone mapper assumed by HDR-FLIP, `cstart` and `cstop` are the shortest and longest exposures, respectively, assumed by HDR-FLIP, with `p` indicating a positive value and `m` indicating a negative value, - `N` is the number of exposures used in the HDR-ꟻLIP calculation, `nnn` is a counter used to sort the intermediate results, - and `exp` is the exposure used for the intermediate LDR image / ꟻLIP map): + `N` is the number of exposures used in the HDR-FLIP calculation, `nnn` is a counter used to sort the intermediate results, + and `exp` is the exposure used for the intermediate LDR image / FLIP map): **Default:** *Low dynamic range images:*
- LDR-ꟻLIP: `flip...ppd.ldr.png`
+ LDR-FLIP: `flip...ppd.ldr.png`
Weighted histogram: `weighted_histogram.reference>..ppd.ldr.py`
Overlapping weighted histogram: `overlapping_weighted_histogram....ppd.ldr.py`
Text file: `pooled_values...ppd.ldr.txt`
*High dynamic range images:*
- HDR-ꟻLIP: `flip...ppd.hdr.._to_..png`
+ HDR-FLIP: `flip...ppd.hdr.._to_..png`
Exposure map: `exposure_map...ppd.hdr.._to_..png`
- Intermediate LDR-ꟻLIP maps: `flip...ppd.ldr....png`
+ Intermediate LDR-FLIP maps: `flip...ppd.ldr....png`
Intermediate LDR images: `....png`
Weighted histogram: `weighted_histogram...ppd.hdr.._to_..py`
Overlapping weighted histogram: `overlapping_weighted_histogram....ppd.hdr.._to_..py`
@@ -94,23 +94,23 @@ For business inquiries, please visit our website and submit the form: [NVIDIA Re *Low dynamic range images:*
- LDR-ꟻLIP: `.png`
+ LDR-FLIP: `.png`
Weighted histogram: `.py`
Overlapping weighted histogram: N/A
Text file: `.txt`
*High dynamic range images:*
- HDR-ꟻLIP: `.png`
+ HDR-FLIP: `.png`
Exposure map: `.exposure_map.png`
- Intermediate LDR-ꟻLIP maps: `..png`
+ Intermediate LDR-FLIP maps: `..png`
Intermediate LDR images: `.reference|test..png`
Weighted histogram: `.py`
Overlapping weighted histogram: N/A
Text file: `.txt`
**Example usage:** -After compiling the `FLIP.sln` project, navigate to the `flip[-cuda].exe` executable and try: +After compiling the `flip_evaluator/cpp/FLIP.sln` project, navigate to the `flip[-cuda].exe` executable and try: ``` flip[-cuda].exe -r ../../../images/reference.exr -t ../../../images/test.exr ``` @@ -132,5 +132,5 @@ FLIP between reference image and test image : Max: 0.962022 Evaluation time: seconds ``` -where `` is the time it took to evaluate HDR-ꟻLIP. In addition, you will now find the files `flip.reference.test.67ppd.hdr.aces.m12.5423_to_p0.9427.14.png` and `exposure_map.reference.test.67ppd.hdr.aces.m12.5423_to_p0.9427.14.png` +where `` is the time it took to evaluate HDR-FLIP. In addition, you will now find the files `flip.reference.test.67ppd.hdr.aces.m12.5423_to_p0.9427.14.png` and `exposure_map.reference.test.67ppd.hdr.aces.m12.5423_to_p0.9427.14.png` in the directory containing the `flip[-cuda].exe` executable, and we urge you to inspect those, which will reveal where the errors in the test image are located. diff --git a/cpp/tool/CMakeLists.txt b/flip_evaluator/cpp/tool/CMakeLists.txt similarity index 100% rename from cpp/tool/CMakeLists.txt rename to flip_evaluator/cpp/tool/CMakeLists.txt diff --git a/cpp/tool/CPP.vcxproj b/flip_evaluator/cpp/tool/CPP.vcxproj similarity index 100% rename from cpp/tool/CPP.vcxproj rename to flip_evaluator/cpp/tool/CPP.vcxproj diff --git a/cpp/tool/CPP.vcxproj.filters b/flip_evaluator/cpp/tool/CPP.vcxproj.filters similarity index 100% rename from cpp/tool/CPP.vcxproj.filters rename to flip_evaluator/cpp/tool/CPP.vcxproj.filters diff --git a/cpp/tool/CUDA.vcxproj b/flip_evaluator/cpp/tool/CUDA.vcxproj similarity index 100% rename from cpp/tool/CUDA.vcxproj rename to flip_evaluator/cpp/tool/CUDA.vcxproj diff --git a/cpp/tool/CUDA.vcxproj.filters b/flip_evaluator/cpp/tool/CUDA.vcxproj.filters similarity index 100% rename from cpp/tool/CUDA.vcxproj.filters rename to flip_evaluator/cpp/tool/CUDA.vcxproj.filters diff --git a/cpp/tool/FLIP-tool.cpp b/flip_evaluator/cpp/tool/FLIP-tool.cpp similarity index 100% rename from cpp/tool/FLIP-tool.cpp rename to flip_evaluator/cpp/tool/FLIP-tool.cpp diff --git a/cpp/tool/FLIP-tool.cu b/flip_evaluator/cpp/tool/FLIP-tool.cu similarity index 100% rename from cpp/tool/FLIP-tool.cu rename to flip_evaluator/cpp/tool/FLIP-tool.cu diff --git a/cpp/tool/FLIPToolHelpers.h b/flip_evaluator/cpp/tool/FLIPToolHelpers.h similarity index 94% rename from cpp/tool/FLIPToolHelpers.h rename to flip_evaluator/cpp/tool/FLIPToolHelpers.h index 32c1dda..7ba0203 100644 --- a/cpp/tool/FLIPToolHelpers.h +++ b/flip_evaluator/cpp/tool/FLIPToolHelpers.h @@ -48,6 +48,7 @@ // Code by Pontus Ebelin (formerly Andersson), Jim Nilsson, and Tomas Akenine-Moller. +#pragma once #include #include #include @@ -232,15 +233,15 @@ namespace FLIPTool } // Optionally store the intermediate LDR images and LDR-FLIP error maps produced during the evaluation of HDR-FLIP. - static void saveHDROutputLDRImages(commandline& commandLine, const FLIP::Parameters& parameters, const std::string& basename, const FLIP::filename& flipFileName, + static void saveIntermediateHDRFLIPOutput(commandline& commandLine, const FLIP::Parameters& parameters, const std::string& basename, const FLIP::filename& flipFileName, const FLIP::filename& referenceFileName, const FLIP::filename& testFileName, const std::string& destinationDirectory, - std::vector*> hdrOutputFlipLDRImages, std::vector*> hdrOutputLDRImages) + std::vector*> intermediateLDRFLIPImages, std::vector*> intermediateLDRImages) { - if (hdrOutputLDRImages.size() > 0) + if (intermediateLDRImages.size() > 0) { - FLIP::filename rFileName(".png"); - FLIP::filename tFileName(".png"); - if (hdrOutputLDRImages.size() != parameters.numExposures * 2) + FLIP::filename rFileName("tmp.png"); + FLIP::filename tFileName("tmp.png"); + if (intermediateLDRImages.size() != size_t(parameters.numExposures * 2)) { std::cout << "FLIP tool error: the number of LDR images from HDR-FLIP is not the expected number.\nExiting.\n"; exit(EXIT_FAILURE); @@ -262,10 +263,10 @@ namespace FLIPTool rFileName.setName(basename + ".reference." + "." + expCount); tFileName.setName(basename + ".test." + "." + expCount); } - FLIP::image* rImage = hdrOutputLDRImages[0]; - FLIP::image* tImage = hdrOutputLDRImages[1]; - hdrOutputLDRImages.erase(hdrOutputLDRImages.begin()); - hdrOutputLDRImages.erase(hdrOutputLDRImages.begin()); + FLIP::image* rImage = intermediateLDRImages[0]; + FLIP::image* tImage = intermediateLDRImages[1]; + intermediateLDRImages.erase(intermediateLDRImages.begin()); + intermediateLDRImages.erase(intermediateLDRImages.begin()); rImage->LinearRGBTosRGB(); tImage->LinearRGBTosRGB(); ImageHelpers::pngSave(destinationDirectory + "/" + rFileName.toString(), *rImage); @@ -274,9 +275,9 @@ namespace FLIPTool delete tImage; } } - if (hdrOutputFlipLDRImages.size() > 0) + if (intermediateLDRFLIPImages.size() > 0) { - if (hdrOutputFlipLDRImages.size() != parameters.numExposures) + if (intermediateLDRFLIPImages.size() != size_t(parameters.numExposures)) { std::cout << "FLIP tool error: the number of FLIP LDR images from HDR-FLIP is not the expected number.\nExiting.\n"; exit(EXIT_FAILURE); @@ -288,8 +289,8 @@ namespace FLIPTool std::string expCount, expString; setExposureStrings(i, parameters.startExposure + i * exposureStepSize, expCount, expString); - FLIP::image* flipImage = hdrOutputFlipLDRImages[0]; - hdrOutputFlipLDRImages.erase(hdrOutputFlipLDRImages.begin()); + FLIP::image* flipImage = intermediateLDRFLIPImages[0]; + intermediateLDRFLIPImages.erase(intermediateLDRFLIPImages.begin()); FLIP::image pngResult(flipImage->getWidth(), flipImage->getHeight()); @@ -468,7 +469,7 @@ namespace FLIPTool { std::string FLIPString = "FLIP"; int MajorVersion = 1; - int MinorVersion = 4; + int MinorVersion = 5; if (commandLine.optionSet("help")) { @@ -509,10 +510,10 @@ namespace FLIPTool bool bUseHDR = (referenceFileName.getExtension() == "exr"); std::string destinationDirectory = "."; std::string basename = (commandLine.optionSet("basename") ? commandLine.getOptionValue("basename") : ""); - FLIP::filename flipFileName(".png"); - FLIP::filename histogramFileName(".py"); - FLIP::filename exposureFileName(".png"); - FLIP::filename txtFileName(".txt"); + FLIP::filename flipFileName("tmp.png"); // Dummy file name, but it keeps the file extension (.png). + FLIP::filename histogramFileName("tmp.py"); + FLIP::filename exposureFileName("tmp.png"); + FLIP::filename txtFileName("tmp.txt"); FLIP::filename testFileName; bool returnLDRImages = false; // Can only happen for HDR. bool returnLDRFLIPImages = false; // Can only happen for HDR. @@ -551,8 +552,8 @@ namespace FLIPTool for (auto& testFileNameString : commandLine.getOptionValues("test")) { pooledValues = FLIPPooling::pooling(100); // Reset pooledValues to remove accumulation issues. - std::vector*> hdrOutputFlipLDRImages; - std::vector*> hdrOutputLDRImages; + std::vector*> intermediateLDRFLIPImages; + std::vector*> intermediateLDRImages; testFileName = testFileNameString; if (!std::filesystem::exists(testFileName.toString())) @@ -583,11 +584,11 @@ namespace FLIPTool FLIP::image maxErrorExposureMap(referenceImage.getWidth(), referenceImage.getHeight()); auto t0 = std::chrono::high_resolution_clock::now(); - FLIP::evaluate(referenceImage, testImage, bUseHDR, parameters, errorMapFLIP, maxErrorExposureMap, returnLDRFLIPImages, hdrOutputFlipLDRImages, returnLDRImages, hdrOutputLDRImages); + FLIP::evaluate(referenceImage, testImage, bUseHDR, parameters, errorMapFLIP, maxErrorExposureMap, returnLDRFLIPImages, intermediateLDRFLIPImages, returnLDRImages, intermediateLDRImages); float time = std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - t0).count() / 1000000.0f; saveErrorAndExposureMaps(bUseHDR, commandLine, parameters, basename, errorMapFLIP, maxErrorExposureMap, destinationDirectory, referenceFileName, testFileName, histogramFileName, txtFileName, flipFileName, exposureFileName, verbosity, testFileCount); - saveHDROutputLDRImages(commandLine, parameters, basename, flipFileName, referenceFileName, testFileName, destinationDirectory, hdrOutputFlipLDRImages, hdrOutputLDRImages); + saveIntermediateHDRFLIPOutput(commandLine, parameters, basename, flipFileName, referenceFileName, testFileName, destinationDirectory, intermediateLDRFLIPImages, intermediateLDRImages); gatherStatisticsAndSaveOutput(commandLine, errorMapFLIP, pooledValues, destinationDirectory, referenceFileName, testFileName, histogramFileName, txtFileName, FLIPString, time, ++testFileCount, saveOverlappedHistogram, verbosity); // Save first set of results for overlapped histogram. diff --git a/cpp/tool/commandline.h b/flip_evaluator/cpp/tool/commandline.h similarity index 99% rename from cpp/tool/commandline.h rename to flip_evaluator/cpp/tool/commandline.h index e4631d3..2e03c63 100644 --- a/cpp/tool/commandline.h +++ b/flip_evaluator/cpp/tool/commandline.h @@ -234,7 +234,7 @@ class commandline { longOptionName = allowedOption.longName; shortOptionName = allowedOption.shortName; - if (bIsLong && longOptionName == optionString || !bIsLong && shortOptionName == optionString) + if ((bIsLong && longOptionName == optionString) || (!bIsLong && shortOptionName == optionString)) { bFound = true; atOption = true; diff --git a/cpp/tool/filename.h b/flip_evaluator/cpp/tool/filename.h similarity index 98% rename from cpp/tool/filename.h rename to flip_evaluator/cpp/tool/filename.h index 61e718b..2a3c32b 100644 --- a/cpp/tool/filename.h +++ b/flip_evaluator/cpp/tool/filename.h @@ -170,7 +170,7 @@ namespace FLIP int fileNameStringLength = int(fileNameString.length()); int totalLength = directoryStringLength + fileNameStringLength; - if (totalLength > maxLen) + if (size_t(totalLength) > maxLen) { // First shorten the directory. int overflow = totalLength - int(maxLen); @@ -412,13 +412,6 @@ namespace FLIP bool parse(std::string path) { init(); - size_t periodCount = std::count_if(path.begin(), path.end(), [](char c) {return c == '.'; }); - if (path[0] == '.' && periodCount == 1) - { - mExtension = path.substr(1); - return true; - } - // Must be at least one slash to contain a directory. size_t iLastSlash = path.find_last_of("\\/"); diff --git a/cpp/tool/imagehelpers.h b/flip_evaluator/cpp/tool/imagehelpers.h similarity index 100% rename from cpp/tool/imagehelpers.h rename to flip_evaluator/cpp/tool/imagehelpers.h diff --git a/cpp/tool/pooling.h b/flip_evaluator/cpp/tool/pooling.h similarity index 99% rename from cpp/tool/pooling.h rename to flip_evaluator/cpp/tool/pooling.h index 7b5f6ff..5edeafe 100644 --- a/cpp/tool/pooling.h +++ b/flip_evaluator/cpp/tool/pooling.h @@ -412,7 +412,6 @@ namespace FLIPPooling size_t numPixels = size_t(imgWidth) * size_t(imgHeight); size_t bucketsSize = firstPooledValues.getHistogram().size(); - size_t bucketsSize2 = this->mHistogram.size(); T bucketStep = this->mHistogram.getBucketStep(); float firstPooledValuesMean = firstPooledValues.getMean(); diff --git a/cpp/tool/stb_image.h b/flip_evaluator/cpp/tool/stb_image.h similarity index 100% rename from cpp/tool/stb_image.h rename to flip_evaluator/cpp/tool/stb_image.h diff --git a/cpp/tool/stb_image_write.h b/flip_evaluator/cpp/tool/stb_image_write.h similarity index 100% rename from cpp/tool/stb_image_write.h rename to flip_evaluator/cpp/tool/stb_image_write.h diff --git a/cpp/tool/tinyexr.h b/flip_evaluator/cpp/tool/tinyexr.h similarity index 100% rename from cpp/tool/tinyexr.h rename to flip_evaluator/cpp/tool/tinyexr.h diff --git a/python/flip/main.py b/flip_evaluator/flip_python_api.py similarity index 96% rename from python/flip/main.py rename to flip_evaluator/flip_python_api.py index 6cdde90..5667dc0 100644 --- a/python/flip/main.py +++ b/flip_evaluator/flip_python_api.py @@ -99,14 +99,6 @@ def evaluate(reference, test, dynamicRangeString, inputsRGB=True, applyMagma=Tru # Evaluate FLIP. Return error map. return pbflip.evaluate(reference, test, useHDR, inputsRGB, computeMeanError, applyMagma, parameters) -def execute(cmdline): - """ - Run the FLIP tool, based on the C++ tool code. - - :param cmdline: string containing the command line for the FLIP tool (run python flip.py to see all available input) - """ - pbflip.execute(cmdline) - def load(imgpath): """ Load an image. @@ -114,4 +106,10 @@ def load(imgpath): :param imgpath: string containing the relative or absolute path to an image, allowed file types are png, exr, bmp, and tga :return: numpy array containing the image (with HxWxC layout) """ - return pbflip.load(imgpath) \ No newline at end of file + return pbflip.load(imgpath) + +def main(): + pbflip.execute(sys.argv) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/images/reference.exr b/flip_evaluator/images/reference.exr similarity index 100% rename from images/reference.exr rename to flip_evaluator/images/reference.exr diff --git a/images/reference.png b/flip_evaluator/images/reference.png similarity index 100% rename from images/reference.png rename to flip_evaluator/images/reference.png diff --git a/images/teaser.png b/flip_evaluator/images/teaser.png similarity index 100% rename from images/teaser.png rename to flip_evaluator/images/teaser.png diff --git a/images/test.exr b/flip_evaluator/images/test.exr similarity index 100% rename from images/test.exr rename to flip_evaluator/images/test.exr diff --git a/images/test.png b/flip_evaluator/images/test.png similarity index 100% rename from images/test.png rename to flip_evaluator/images/test.png diff --git a/misc/CLA.md b/flip_evaluator/misc/CLA.md similarity index 100% rename from misc/CLA.md rename to flip_evaluator/misc/CLA.md diff --git a/misc/FLIP.txt b/flip_evaluator/misc/FLIP.txt similarity index 100% rename from misc/FLIP.txt rename to flip_evaluator/misc/FLIP.txt diff --git a/misc/HDRFLIP.txt b/flip_evaluator/misc/HDRFLIP.txt similarity index 100% rename from misc/HDRFLIP.txt rename to flip_evaluator/misc/HDRFLIP.txt diff --git a/misc/LDRFLIP.txt b/flip_evaluator/misc/LDRFLIP.txt similarity index 100% rename from misc/LDRFLIP.txt rename to flip_evaluator/misc/LDRFLIP.txt diff --git a/misc/LICENSE-third-party.md b/flip_evaluator/misc/LICENSE-third-party.md similarity index 100% rename from misc/LICENSE-third-party.md rename to flip_evaluator/misc/LICENSE-third-party.md diff --git a/misc/papersUsingFLIP.md b/flip_evaluator/misc/papersUsingFLIP.md similarity index 99% rename from misc/papersUsingFLIP.md rename to flip_evaluator/misc/papersUsingFLIP.md index 2d7eeca..f1b94e9 100644 --- a/misc/papersUsingFLIP.md +++ b/flip_evaluator/misc/papersUsingFLIP.md @@ -1,8 +1,8 @@ -# List of papers/code that are using/citing ꟻLIP +# List of papers/code that are using/citing FLIP -Please let us know if you know of more papers that use/cite ꟻLIP. +Please let us know if you know of more papers that use/cite FLIP. -**Using ꟻLIP:** +**Using FLIP:** 1. Jae-Ho Nah, ["QuickETC2: Fast ETC2 texture compression using Luma differences"](https://dl.acm.org/doi/abs/10.1145/3414685.3417787), *ACM Transactions on Graphics (SIGGRAPH Asia)*, November 2020 Article No. 270 1. Johanna Engman and Hanna Nilsson, ["A Novel Perceptual Metric in Machine Learning"](https://lup.lub.lu.se/luur/download?func=downloadFile&recordOId=9022150&fileOId=9022160), Master's thesis, Lund University, 2020. @@ -315,13 +315,12 @@ Distant Lighting of Heterogeneous Translucent Objects"](https://people.compute.d 1. Arturo Salmi, Szabolcs Cséfalvay, James Imber, ["Fast Local Neural Regression for Low-Cost, Path Traced Lambertian Global Illumination"](https://arxiv.org/abs/2410.11625), arXiv:2410.11625, 2024. -1. Yu-Ting Wu, ["Efficient Environment Map Rendering Based on Decomposition"](https://onlinelibrary.wiley.com/doi/abs/10.1111/cgf.15264), Computer Graphics Forum, October 2024. -**Citing ꟻLIP (but not using):** +**Citing FLIP (but not using):** 1. Jim Nilsson and Tomas Akenine-Möller, ["Understanding SSIM"](https://arxiv.org/pdf/2006.13846.pdf), *arXiv:2006.13846v2*, 2020. 1. Michael N. Mishourovsky, "Visually Lossless Colour Compression Technology", in *Smart Algorithms for Multimedia and Imaging*, edited by Michael N. Rychagov, Ekaterina V. Tolstaya, and Mikhail Y. Sirotenko, 2021. @@ -390,7 +389,7 @@ ACM Transactions on Graphics (Proceedings of SIGGRAPH ASIA), 2021. 1. Rafail Nikou, Aristeidis Tsaknis, Paschalis Margaritis, Stylianos Alvanos, Konstantinos-Filippos Kollias, George S. Maraslidis, Nikolaos Asimopoulos, Panagiotis Sarigiannidis, Vasileios Argyriou, George F. Fragulis, ["Machine learning data-based approaches for autism spectrum disorder classification utilising facial images"](https://pubs.aip.org/aip/acp/article-abstract/3220/1/050013/3315891/Machine-learning-data-based-approaches-for-autism), AIP Conference Proceedings, October 2024. -**Code/frameworks/tools that use ꟻLIP:** +**Code/frameworks/tools that use FLIP:** 1. [Falcor](https://github.com/NVIDIAGameWorks/Falcor). 1. [The FLOꟼ tool](https://github.com/jeremyong/flop/releases/tag/v1.618). diff --git a/misc/precision.md b/flip_evaluator/misc/precision.md similarity index 93% rename from misc/precision.md rename to flip_evaluator/misc/precision.md index ffe740c..6790ac6 100644 --- a/misc/precision.md +++ b/flip_evaluator/misc/precision.md @@ -1,6 +1,6 @@ # A note about precision -We have several different implementations of ꟻLIP (Python, PyTorch, C++, and CUDA) and we have tried to make +We have several different implementations of FLIP (Python, PyTorch, C++, and CUDA) and we have tried to make the implementations as similar as possible. However, there are several facts about these that make it very hard to get perfect matches between the implementations. These include: diff --git a/misc/separatedConvolutions.pdf b/flip_evaluator/misc/separatedConvolutions.pdf similarity index 100% rename from misc/separatedConvolutions.pdf rename to flip_evaluator/misc/separatedConvolutions.pdf diff --git a/misc/versionList.md b/flip_evaluator/misc/versionList.md similarity index 73% rename from misc/versionList.md rename to flip_evaluator/misc/versionList.md index 556cf61..8881cbe 100644 --- a/misc/versionList.md +++ b/flip_evaluator/misc/versionList.md @@ -1,21 +1,32 @@ -# ꟻLIP Version List +# FLIP Version List In addition to various minor changes, the following was -changed for the different versions of ꟻLIP: +changed for the different versions of FLIP: + +# Version 1.5 (commit ?) +- Flipped the ꟻ in ꟻLIP. The entire name (FLIP) should now be readable on all devices. +- Published Python version of FLIP to PyPI (URL: ?). + - The distribution has been tested on Windows, Linux (Ubuntu), and macOS. + - The Python version of FLIP (tool and API) is now installed by `pip install flip-evaluator`. + - After installation, the tool can be run directly in a shell by `flip --reference reference.{png|exr} --test test.{png|exr}`. + - After installation, the FLIP API is available in Python by `import flip_evaluator as flip`. +- Directory structure in the FLIP repository has been altered to accomodate the Python version being published to PyPI. +- Updated Python/C++/CUDA test script. +- Various bugfixes. # Version 1.4 (commits 6265f80 to 0349494) -- Changed the Python version of ꟻLIP so that it leverages the C++ code through [pybind11](https://github.com/pybind/pybind11). +- Changed the Python version of FLIP so that it leverages the C++ code through [pybind11](https://github.com/pybind/pybind11). - Results (only evaluation, not including file load/save, etc; measured on an AMD Ryzen Threadripper 3970X 32-Core Processor, 3693 MHz, with 32 Cores and 64 Logical Processors): - 20-47x faster for LDR/HDR CPU. - Timings for 1920x1080 images: - Python/LDR: 77 ms - Python/HDR: 1007 ms - - **NOTE**: The Python version can currently _not_ run the CUDA version of ꟻLIP (see issue [#22](https://github.com/NVlabs/flip/issues/22)). + - **NOTE**: The Python version can currently _not_ run the CUDA version of FLIP (see issue [#22](https://github.com/NVlabs/flip/issues/22)). - **NOTE**: The Python tool now uses the C++ tool. Compared to before, you will need to change `_` to `-` when calling flip.py (e.g., `python flip.py -r reference.exr -t test.exr --start_exposure 3` is now `python flip.py -r reference.exr -t test.exr --start-exposure 3`; see `python flip.py -h`). -- The Python version of ꟻLIP can now be installed using `pip` (run `pip install -r requirements.txt .` from the `python` folder). +- The Python version of FLIP can now be installed using `pip` (run `pip install -r requirements.txt .` from the `python` folder). - The code for the C++/CUDA tool is now in `FLIPToolHelpers.h`. - **NOTE**: The fourth `evaluate()` function in `FLIP.h` now takes two additional arguments: `computeMeanError` and `meanError`. Furthermore, its list of arguments has been partly reordered. -- **NOTE**: The median computation (used for automatic start and stop expsoure computations in HDR-ꟻLIP) in the C++/CUDA code has been changed, sometimes causing a minor change in results but always resulting in a significant speedup. The tests have been updated following this change. +- **NOTE**: The median computation (used for automatic start and stop expsoure computations in HDR-FLIP) in the C++/CUDA code has been changed, sometimes causing a minor change in results but always resulting in a significant speedup. The tests have been updated following this change. - Timings for 1920x1080 images (only evaluation, not including file load/save, etc, *but* measured with another GPU and including more code than the numbers presented in the v1.2 update, so the numbers are not directly comparable; measured on an AMD Ryzen Threadripper 3970X 32-Core Processor, 3693 MHz, with 32 Cores and 64 Logical Processors and an NVIDIA RTX 4090 GPU): - CPP/LDR: 86 ms - CPP/HDR: 1179 ms @@ -28,7 +39,7 @@ changed for the different versions of ꟻLIP: # Version 1.3 (commit a00bc7d) - Changed to CUDA 12.3. -- Rewrote C++ code so that ꟻLIP is in a single header (both CPP/CUDA). +- Rewrote C++ code so that FLIP is in a single header (both CPP/CUDA). - Rewrote `FLIP-tool.cpp` to use many more local functions to make the code easier to read. - Some of the `tests/correct_*.png` images have been update due to minor changes in output that occurred as part of switching to CUDA 12.3 and changing the order of some transforms. @@ -50,7 +61,7 @@ changed for the different versions of ꟻLIP: - CUDA/HDR: 136 ms # Version 1.1 (commit 4ed59e9) -- NVIDIA Source Code License changed to a 3-Clause BSD License +- NVIDIA Source Code License changed to a BSD 3-Clause License - Precision updates: - Constants use nine decimal digits (a float32 number has the same bit representation if stored with nine or more decimals in NumPy diff --git a/python/flip/main.cpp b/flip_evaluator/pybindFLIP.cpp similarity index 92% rename from python/flip/main.cpp rename to flip_evaluator/pybindFLIP.cpp index 11df041..21af1ff 100644 --- a/python/flip/main.cpp +++ b/flip_evaluator/pybindFLIP.cpp @@ -48,13 +48,12 @@ // Code by Pontus Ebelin (formerly Andersson) and Tomas Akenine-Moller. -#pragma once #include #include #include -#include "../../cpp/FLIP.h" -#include "../../cpp/tool/FLIPToolHelpers.h" +#include "cpp/FLIP.h" +#include "cpp/tool/FLIPToolHelpers.h" namespace py = pybind11; @@ -77,16 +76,6 @@ py::array_t load(std::string fileName) return numpyImage; } -// Convert linear RGB channel value to sRGB. -float sRGBToLinearRGB(float sC) -{ - if (sC <= 0.04045f) - { - return sC / 12.92f; - } - return powf((sC + 0.055f) / 1.055f, 2.4f); -} - // Convert linear RGB image to sRGB. void sRGBToLinearRGB(float* image, const int imageWidth, const int imageHeight) { @@ -96,9 +85,9 @@ void sRGBToLinearRGB(float* image, const int imageWidth, const int imageHeight) for (int x = 0; x < imageWidth; x++) { int idx = (y * imageWidth + x) * 3; - image[idx] = sRGBToLinearRGB(image[idx]); - image[idx + 1] = sRGBToLinearRGB(image[idx + 1]); - image[idx + 2] = sRGBToLinearRGB(image[idx + 2]); + image[idx] = FLIP::color3::sRGBToLinearRGB(image[idx]); + image[idx + 1] = FLIP::color3::sRGBToLinearRGB(image[idx + 1]); + image[idx + 2] = FLIP::color3::sRGBToLinearRGB(image[idx + 2]); } } } @@ -122,7 +111,7 @@ FLIP::Parameters setParameters(py::dict inputParameters) float distanceToDisplay = py::cast(vc[0]); float displayWidthPixels = py::cast(vc[1]); float displayWidthMeters = py::cast(vc[2]); - parameters.PPD = FLIP::calculatePPD(distanceToDisplay, displayWidthPixels, displayWidthPixels); + parameters.PPD = FLIP::calculatePPD(distanceToDisplay, displayWidthPixels, displayWidthMeters); } else if (key == "startExposure") { @@ -194,7 +183,7 @@ std::tuple, float, py::dict> evaluate(const py::array_t(t_buf.ptr); // Image size. - const int nRows = int(r_buf.shape[0]), nCols = int(r_buf.shape[1]), nChannels = int(r_buf.shape[2]); + const int nRows = int(r_buf.shape[0]), nCols = int(r_buf.shape[1]); // FLIP float* flip; @@ -204,13 +193,13 @@ std::tuple, float, py::dict> evaluate(const py::array_t({ r_buf.shape[0], r_buf.shape[1], r_buf.shape[2] }); nChannelsOut = 3; + flipNumpy = py::array_t({ nRows, nCols, nChannelsOut}); } else { - flipNumpy = py::array_t({ r_buf.shape[0], r_buf.shape[1] }); nChannelsOut = 1; + flipNumpy = py::array_t({ nRows, nCols }); } py::buffer_info flipNumpy_buf = flipNumpy.request(); float* ptr_flipNumpy = static_cast(flipNumpy_buf.ptr); @@ -258,8 +247,7 @@ commandline generateCommandLine(const py::list argvPy) for (auto item : argvPy) { const std::string it = py::reinterpret_steal(item); - argv[counter] = new char[it.length()]; - std::strcpy(argv[counter], it.c_str()); + argv[counter] = strdup(it.c_str()); counter++; } @@ -287,7 +275,7 @@ int execute(const py::list argvPy) PYBIND11_MODULE(pbflip, handle) { handle.doc() = "Load images (load), evaluate FLIP (evaluate), or run the full FLIP tool (execute)."; - handle.def("evaluate", &evaluate); handle.def("load", &load); + handle.def("evaluate", &evaluate); handle.def("execute", &execute); -} +} \ No newline at end of file diff --git a/python/README.md b/flip_evaluator/python/README.md similarity index 55% rename from python/README.md rename to flip_evaluator/python/README.md index dca085a..76c494e 100644 --- a/python/README.md +++ b/flip_evaluator/python/README.md @@ -1,7 +1,7 @@ -# ꟻLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.4) +# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.5) By -[Pontus Ebelin](https://research.nvidia.com/person/pontus-ebelin), +[Pontus Ebelin](https://research.nvidia.com/person/pontus-ebelin) and [Tomas Akenine-Möller](https://research.nvidia.com/person/tomas-akenine-m%C3%B6ller), with @@ -12,15 +12,15 @@ Jim Nilsson, and [Peter Shirley](https://research.nvidia.com/person/peter-shirley). -This [repository](https://github.com/NVlabs/flip) implements the [LDR-ꟻLIP](https://research.nvidia.com/publication/2020-07_FLIP) -and [HDR-ꟻLIP](https://research.nvidia.com/publication/2021-05_HDR-FLIP) image error metrics in Python, using the C++ implementation through [pybind11](https://github.com/pybind/pybind11). -Similarly, it implements the ꟻLIP tool, presented in [Ray Tracing Gems II](https://www.realtimerendering.com/raytracinggems/rtg2/index.html). +This [repository](https://github.com/NVlabs/flip) implements the [LDR-FLIP](https://research.nvidia.com/publication/2020-07_FLIP) +and [HDR-FLIP](https://research.nvidia.com/publication/2021-05_HDR-FLIP) image error metrics in Python, using the C++ implementation through [pybind11](https://github.com/pybind/pybind11). +Similarly, it implements the FLIP tool, presented in [Ray Tracing Gems II](https://www.realtimerendering.com/raytracinggems/rtg2/index.html). # License Copyright © 2020-2024, NVIDIA Corporation & Affiliates. All rights reserved. -This work is made available under a [BSD 3-Clause License](../misc/LICENSE.md). +This work is made available under a [BSD 3-Clause License](../../LICENSE). The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](../misc/LICENSE-third-party.md#bsd-3-clause-license),
and `stb_image`, which is subject to an [MIT License](../misc/LICENSE-third-party.md#mit-license). @@ -30,39 +30,36 @@ For individual contributions to the project, please confer the [Individual Contr For business inquiries, please visit our website and submit the form: [NVIDIA Research Licensing](https://www.nvidia.com/en-us/research/inquiries/). # Python (API and Tool) -- **Setup** (with pip, from root directory): +- **Setup** (with pip): ``` - cd python - pip install -r requirements.txt . + pip install flip-evaluator ``` - After this, you may `import flip` from any Python script. -- Usage (API): See example in the script `flip/api_example.py`. Note that the script requires `matplotlib`. -- Usage (tool): `python flip.py --reference reference.{exr|png} --test test.{exr|png} [--options]`, where the list of options can be seen by `python flip.py -h`. +- Usage (API): See example in the script `flip_evaluator/python/api_example.py`. +- Usage (tool): `flip --reference reference.{exr|png} --test test.{exr|png} [--options]`, where the list of options can be seen by `flip -h`. - Tested with pip 24.0, Python 3.11.8, pybind11 2.11.1, and C++20. -- The code that implements ꟻLIP metrics and the ꟻLIP tool is available in [FLIP.h](https://github.com/NVlabs/flip/blob/main/cpp/FLIP.h) and [flip/cpp/tool](https://github.com/NVlabs/flip/blob/main/cpp/tool), respectively. - The Python API is provided in `flip/python/flip/main.py`. - `../tests/test.py` contains simple tests used to test whether code updates alter results. +- The code that implements FLIP metrics and the FLIP tool is available in [flip_evaluator/cpp/FLIP.h](https://github.com/NVlabs/flip/blob/main/cpp/FLIP.h) and [flip_evaluator/cpp/tool](https://github.com/NVlabs/flip/blob/main/cpp/tool), respectively. The relevant functions are called by the Python API using [pybind11](https://github.com/pybind/pybind11) (see [flip_evaluator/main.cpp](https://github.com/NVlabs/flip/blob/main/flip_evaluator/main.cpp)). The Python API is provided in `flip_evaluator/main.py`. + `flip_evaluator/tests/test.py` contains simple tests used to test whether code updates alter results. - Weighted histograms are output as Python scripts. Running the script will create a PDF version of the histogram. Notice that those scripts require `numpy` and `matplotlib`, both of which are automatically installed during setup. -- The naming convention used for the ꟻLIP tool's output is as follows (where `ppd` is the assumed number of pixels per degree, - `tm` is the tone mapper assumed by HDR-ꟻLIP, `cstart` and `cstop` are the shortest and longest exposures, respectively, assumed by HDR-ꟻLIP, +- The naming convention used for the FLIP tool's output is as follows (where `ppd` is the assumed number of pixels per degree, + `tm` is the tone mapper assumed by HDR-FLIP, `cstart` and `cstop` are the shortest and longest exposures, respectively, assumed by HDR-FLIP, with `p` indicating a positive value and `m` indicating a negative value, - `N` is the number of exposures used in the HDR-ꟻLIP calculation, `nnn` is a counter used to sort the intermediate results, - and `exp` is the exposure used for the intermediate LDR image / ꟻLIP map): + `N` is the number of exposures used in the HDR-FLIP calculation, `nnn` is a counter used to sort the intermediate results, + and `exp` is the exposure used for the intermediate LDR image / FLIP map): **Default:** *Low dynamic range images:*
- LDR-ꟻLIP: `flip...ppd.ldr.png`
+ LDR-FLIP: `flip...ppd.ldr.png`
Weighted histogram: `weighted_histogram.reference>..ppd.ldr.py`
Overlapping weighted histogram: `overlapping_weighted_histogram....ppd.ldr.py`
Text file: `pooled_values...ppd.ldr.txt`
*High dynamic range images:*
- HDR-ꟻLIP: `flip...ppd.hdr.._to_..png`
+ HDR-FLIP: `flip...ppd.hdr.._to_..png`
Exposure map: `exposure_map...ppd.hdr.._to_..png`
- Intermediate LDR-ꟻLIP maps: `flip...ppd.ldr....png`
+ Intermediate LDR-FLIP maps: `flip...ppd.ldr....png`
Intermediate LDR images: `....png`
Weighted histogram: `weighted_histogram...ppd.hdr.._to_..py`
Overlapping weighted histogram: `overlapping_weighted_histogram....ppd.hdr.._to_..py`
@@ -72,28 +69,28 @@ For business inquiries, please visit our website and submit the form: [NVIDIA Re *Low dynamic range images:*
- LDR-ꟻLIP: `.png`
+ LDR-FLIP: `.png`
Weighted histogram: `.py`
Overlapping weighted histogram: N/A
Text file: `.txt`
*High dynamic range images:*
- HDR-ꟻLIP: `.png`
+ HDR-FLIP: `.png`
Exposure map: `.exposure_map.png`
- Intermediate LDR-ꟻLIP maps: `..png`
+ Intermediate LDR-FLIP maps: `..png`
Intermediate LDR images: `.reference|test..png`
Weighted histogram: `.py`
Overlapping weighted histogram: N/A
Text file: `.txt`
**Example usage:** -To test the API, please inspect the `flip/api_example.py` script. This shows how the available API commands may be used. Note that the script requires `matplotlib`. -Please note that not all capabilities of the tool is available through the Python API. For example, the exposure map is not output when running HDR-ꟻLIP. For that, use the tool or the C++ API in [FLIP.h](https://github.com/NVlabs/flip/blob/main/cpp/FLIP.h). +To test the API, please inspect the `flip_evaluator/python/api_example.py` script. This shows how the available API commands may be used. Note that the script requires `matplotlib`. +Please note that not all capabilities of the tool is available through the Python API. For example, the exposure map is not output when running HDR-FLIP. For that, use the tool or the C++ API in [FLIP.h](https://github.com/NVlabs/flip/blob/main/cpp/FLIP.h). -To test the tool, first navigate to the directory containing the `flip.py` script. Then start a shell and try: +To test the tool, start a shell, navigate to `flip_evaluator/python` and try: ``` - python flip.py -r ../images/reference.exr -t ../images/test.exr + flip -r ../images/reference.exr -t ../images/test.exr ``` The result should be: ``` @@ -113,5 +110,5 @@ FLIP between reference image and test image : Max: 0.962022 Evaluation time: seconds ``` -where `` is the time it took to evaluate HDR-ꟻLIP. In addition, you will now find the files `flip.reference.test.67ppd.hdr.aces.m12.5423_to_p0.9427.14.png` and `exposure_map.reference.test.67ppd.hdr.aces.m12.5423_to_p0.9427.14.png` -in the directory containing the `flip.py` script, and we urge you to inspect those, which will reveal where the errors in the test image are located. +where `` is the time it took to evaluate HDR-FLIP. In addition, you will now find the files `flip.reference.test.67ppd.hdr.aces.m12.5423_to_p0.9427.14.png` and `exposure_map.reference.test.67ppd.hdr.aces.m12.5423_to_p0.9427.14.png` +in the working directory, and we urge you to inspect those, which will reveal where the errors in the test image are located. diff --git a/python/api_example.py b/flip_evaluator/python/api_example.py similarity index 99% rename from python/api_example.py rename to flip_evaluator/python/api_example.py index d0848ec..37872ca 100644 --- a/python/api_example.py +++ b/flip_evaluator/python/api_example.py @@ -30,7 +30,7 @@ # SPDX-License-Identifier: BSD-3-Clause ################################################################################# -import flip +import flip_evaluator as flip import matplotlib.pyplot as plt if __name__ == '__main__': diff --git a/pytorch/README.md b/flip_evaluator/pytorch/README.md similarity index 72% rename from pytorch/README.md rename to flip_evaluator/pytorch/README.md index a1eec2e..05e6162 100644 --- a/pytorch/README.md +++ b/flip_evaluator/pytorch/README.md @@ -1,7 +1,7 @@ -# ꟻLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.4) +# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.5) By -[Pontus Ebelin](https://research.nvidia.com/person/pontus-ebelin), +[Pontus Ebelin](https://research.nvidia.com/person/pontus-ebelin) and [Tomas Akenine-Möller](https://research.nvidia.com/person/tomas-akenine-m%C3%B6ller), with @@ -12,14 +12,14 @@ Jim Nilsson, and [Peter Shirley](https://research.nvidia.com/person/peter-shirley). -This [repository](https://github.com/NVlabs/flip) holds implementations of the [LDR-ꟻLIP](https://research.nvidia.com/publication/2020-07_FLIP) -and [HDR-ꟻLIP](https://research.nvidia.com/publication/2021-05_HDR-FLIP) image error metrics as loss modules in PyTorch. +This [repository](https://github.com/NVlabs/flip) holds implementations of the [LDR-FLIP](https://research.nvidia.com/publication/2020-07_FLIP) +and [HDR-FLIP](https://research.nvidia.com/publication/2021-05_HDR-FLIP) image error metrics as loss modules in PyTorch. # License Copyright © 2020-2024, NVIDIA Corporation & Affiliates. All rights reserved. -This work is made available under a [BSD 3-Clause License](../misc/LICENSE.md). +This work is made available under a [BSD 3-Clause License](../../LICENSE). The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](../misc/LICENSE-third-party.md#bsd-3-clause-license),
and `stb_image`, which is subject to an [MIT License](../misc/LICENSE-third-party.md#mit-license). @@ -38,25 +38,25 @@ For business inquiries, please visit our website and submit the form: [NVIDIA Re conda install -c conda-forge openexr-python ``` - *Remember to activate the* `flip_dl` *environment through* `conda activate flip_dl` *before using the loss function.* -- LDR- and HDR-ꟻLIP are implemented as loss modules in `flip_loss.py`. - An example where the loss function is used to train a simple autoencoder is provided in `train.py`. +- LDR- and HDR-FLIP are implemented as loss modules in `flip_evaluator/pytorch/flip_loss.py`. + An example where the loss function is used to train a simple autoencoder is provided in `flip_evaluator/pytorch/train.py`. - Tested on Windows with Conda 4.10.0, CUDA 11.2, Python 3.9.4, PyTorch 1.8.1, NumPy 1.20.1, and OpenEXR b1.3.2. - Per default, the loss function returns the mean of the error maps. To return the full error maps, remove `torch.mean()` from the `forward()` function. -- For LDR-ꟻLIP, the images are assumed to be in sRGB space +- For LDR-FLIP, the images are assumed to be in sRGB space (change the color space transform in `LDRFLIPLoss`'s `forward()` function to `linrgb2ycxcz` if your network's output is in linear RGB), in the [0,1] range. -- Both LDR- and HDR-ꟻLIP takes an optional argument describing the assumed number of pixels per +- Both LDR- and HDR-FLIP takes an optional argument describing the assumed number of pixels per degree of the observer. Per default, it is assume that the images are viewed at a distance 0.7 m from a 0.7 m wide 4K monitor. - The `HDRFLIPLoss` can take three additional, optional arguments: `tone_mapper`, `start_exposure`, and `stop_exposure`. - `tone_mapper` is a string describing the tone mapper that HDR-ꟻLIP should assume, for which the choices are `aces` (default), `hable`, and `reinhard`. The default assumption is the [ACES](https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/) tone mapper. + `tone_mapper` is a string describing the tone mapper that HDR-FLIP should assume, for which the choices are `aces` (default), `hable`, and `reinhard`. The default assumption is the [ACES](https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/) tone mapper. `start_exposure`, and `stop_exposure` should have `Nx1x1x1` layout and hold the start and stop exposures, respectively, used for each of the `N` reference/test pairs in the batch. Per default, `HDRFLIPLoss` computes start and stop exposures as described in the [paper](https://d1qx31qr3h6wln.cloudfront.net/publications/HDRFLIP-paper.pdf). - **NOTE:** When start and/or stop exposures are not provided, HDR-ꟻLIP is not symmetric. The + **NOTE:** When start and/or stop exposures are not provided, HDR-FLIP is not symmetric. The user should therefore make sure to input the test images as the *first* argument and the reference image as the *second* argument to the `HDRFLIPLoss`'s `forward()` function. -- `../tests/test_pytorch.py` contains simple tests used to test whether code updates alter results and - `data.py` contains image loading/saving functions. +- `flip_evaluator/tests/test_pytorch.py` contains simple tests used to test whether code updates alter results and + `flip_evaluator/pytorch/data.py` contains image loading/saving functions. diff --git a/pytorch/data.py b/flip_evaluator/pytorch/data.py similarity index 100% rename from pytorch/data.py rename to flip_evaluator/pytorch/data.py diff --git a/pytorch/flip_loss.py b/flip_evaluator/pytorch/flip_loss.py similarity index 100% rename from pytorch/flip_loss.py rename to flip_evaluator/pytorch/flip_loss.py diff --git a/pytorch/train.py b/flip_evaluator/pytorch/train.py similarity index 100% rename from pytorch/train.py rename to flip_evaluator/pytorch/train.py diff --git a/tests/correct_hdrflip_cpp.png b/flip_evaluator/tests/correct_hdrflip_cpp.png similarity index 100% rename from tests/correct_hdrflip_cpp.png rename to flip_evaluator/tests/correct_hdrflip_cpp.png diff --git a/tests/correct_hdrflip_cuda.png b/flip_evaluator/tests/correct_hdrflip_cuda.png similarity index 100% rename from tests/correct_hdrflip_cuda.png rename to flip_evaluator/tests/correct_hdrflip_cuda.png diff --git a/tests/correct_ldrflip_cpp.png b/flip_evaluator/tests/correct_ldrflip_cpp.png similarity index 100% rename from tests/correct_ldrflip_cpp.png rename to flip_evaluator/tests/correct_ldrflip_cpp.png diff --git a/tests/correct_ldrflip_cuda.png b/flip_evaluator/tests/correct_ldrflip_cuda.png similarity index 100% rename from tests/correct_ldrflip_cuda.png rename to flip_evaluator/tests/correct_ldrflip_cuda.png diff --git a/tests/test.py b/flip_evaluator/tests/test.py similarity index 78% rename from tests/test.py rename to flip_evaluator/tests/test.py index bb7f092..c38e5fa 100644 --- a/tests/test.py +++ b/flip_evaluator/tests/test.py @@ -51,7 +51,9 @@ import subprocess import os import sys -import flip +import matplotlib.pyplot as plt +import numpy as np +import flip_evaluator as flip if __name__ == '__main__': """ @@ -61,7 +63,7 @@ if(len(sys.argv) != 2): print("Usage: python test.py --{cuda|cpp|python}") - print("Tip: do not forget to install the FLIP Python API through `pip install .` in `flip/python`.") + print("Tip: do not forget to install the FLIP Python API through `pip install flip_evaluator`.") sys.exit() # Parse command line argument. @@ -71,24 +73,16 @@ correct_hdr_image_filename = "correct_hdrflip_cuda.png" ldr_cmd = "../cpp/x64/release/flip-cuda.exe --reference ../images/reference.png --test ../images/test.png" hdr_cmd = "../cpp/x64/release/flip-cuda.exe --reference ../images/reference.exr --test ../images/test.exr --no-exposure-map" - expected_ldr_mean = 0.159691 - expected_hdr_mean = 0.283478 elif(sys.argv[1] == "--cpp" or sys.argv[1] == "cpp" or sys.argv[1] == "-cpp"): test_str = "CPP" correct_ldr_image_filename = "correct_ldrflip_cpp.png" correct_hdr_image_filename = "correct_hdrflip_cpp.png" ldr_cmd = "../cpp/x64/release/flip.exe --reference ../images/reference.png --test ../images/test.png" hdr_cmd = "../cpp/x64/release/flip.exe --reference ../images/reference.exr --test ../images/test.exr --no-exposure-map" - expected_ldr_mean = 0.159691 - expected_hdr_mean = 0.283478 elif(sys.argv[1] == "--python" or sys.argv[1] == "python" or sys.argv[1] == "-python"): test_str = "PYTHON" correct_ldr_image_filename = "correct_ldrflip_cpp.png" # Python and C++ should give the same results, correct_hdr_image_filename = "correct_hdrflip_cpp.png" # as the Python code runs the C++ code via pybind11. - ldr_cmd = "python ../python/flip.py --reference ../images/reference.png --test ../images/test.png" - hdr_cmd = "python ../python/flip.py --reference ../images/reference.exr --test ../images/test.exr --no-exposure-map" - expected_ldr_mean = 0.159691 - expected_hdr_mean = 0.283478 else: print("Error: the argument should be one of --cuda, --cpp, and --python.") sys.exit() @@ -100,21 +94,38 @@ ldr_correct_result = flip.load(correct_ldr_image_filename) # LDR, sRGB hdr_correct_result = flip.load(correct_hdr_image_filename) # HDR - # Run FLIP on the reference/test image pairs in the ../images directory. - ldr_process = subprocess.run(ldr_cmd, stdout=subprocess.PIPE, text=True) - hdr_process = subprocess.run(hdr_cmd, stdout=subprocess.PIPE, text=True) + # Result file names + result_ldr_file = "flip.reference.test.67ppd.ldr.png" + result_hdr_file = "flip.reference.test.67ppd.hdr.aces.m12.5423_to_p0.9427.14.png" - ldr_result_strings = ldr_process.stdout.split('\n') - subpos = ldr_result_strings[4].find(':') - ldr_mean = float(ldr_result_strings[4][subpos + 2 : len(ldr_result_strings[4])]) + # Expected means + expected_ldr_mean = 0.159691 + expected_hdr_mean = 0.283478 - hdr_result_strings = hdr_process.stdout.split('\n') - subpos = hdr_result_strings[8].find(':') - hdr_mean = float(hdr_result_strings[8][subpos + 2 : len(hdr_result_strings[4])]) + if test_str == "CUDA" or test_str == "CPP": + # Run FLIP on the reference/test image pairs in the ../images directory. + ldr_process = subprocess.run(ldr_cmd, stdout=subprocess.PIPE, text=True) + hdr_process = subprocess.run(hdr_cmd, stdout=subprocess.PIPE, text=True) - # Load the images that were just created. - result_ldr_file = "flip.reference.test.67ppd.ldr.png" - result_hdr_file = "flip.reference.test.67ppd.hdr.aces.m12.5423_to_p0.9427.14.png" + ldr_result_strings = ldr_process.stdout.split('\n') + subpos = ldr_result_strings[4].find(':') + ldr_mean = float(ldr_result_strings[4][subpos + 2 : len(ldr_result_strings[4])]) + + hdr_result_strings = hdr_process.stdout.split('\n') + subpos = hdr_result_strings[8].find(':') + hdr_mean = float(hdr_result_strings[8][subpos + 2 : len(hdr_result_strings[4])]) + else: + # Run FLIP on the reference/test image pairs in the ../images directory. + ldr_new_result, ldr_mean, _ = flip.evaluate("../images/reference.png", "../images/test.png", "LDR") + hdr_new_result, hdr_mean, _ = flip.evaluate("../images/reference.exr", "../images/test.exr", "HDR") + + # Round to match the FLIP tool's output rounding + ldr_mean = round(ldr_mean, 6) + hdr_mean = round(hdr_mean, 6) + plt.imsave(result_ldr_file, np.uint8(255 * ldr_new_result + 0.5), vmin=0, vmax=255) # Same rounding as is used to save + plt.imsave(result_hdr_file, np.uint8(255 * hdr_new_result + 0.5), vmin=0, vmax=255) # images in the C++ code (cpp/FLIP.h#L1300). + + # Load the images that were just created ldr_new_result = flip.load(result_ldr_file) # LDR, sRGB hdr_new_result = flip.load(result_hdr_file) # HDR diff --git a/tests/test_pytorch.py b/flip_evaluator/tests/test_pytorch.py similarity index 100% rename from tests/test_pytorch.py rename to flip_evaluator/tests/test_pytorch.py diff --git a/misc/LICENSE.md b/misc/LICENSE.md deleted file mode 100644 index 0bb5e47..0000000 --- a/misc/LICENSE.md +++ /dev/null @@ -1,28 +0,0 @@ -# BSD 3-Clause License - -Copyright (c) 2020-2024, NVIDIA Corporation & AFFILIATES. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/python/pyproject.toml b/pyproject.toml similarity index 96% rename from python/pyproject.toml rename to pyproject.toml index e6a7982..8155b5f 100644 --- a/python/pyproject.toml +++ b/pyproject.toml @@ -36,5 +36,5 @@ requires = [ ] [project] -name = "flip" -dynamic = ['version', 'description', 'readme', 'requires-python', 'license', 'authors'] \ No newline at end of file +name = "flip_evaluator" +dynamic = ['version', 'description', 'readme', 'requires-python', 'license', 'authors', 'scripts', 'dependencies'] \ No newline at end of file diff --git a/python/flip.py b/python/flip.py deleted file mode 100644 index 4421d01..0000000 --- a/python/flip.py +++ /dev/null @@ -1,39 +0,0 @@ -################################################################################# -# Copyright (c) 2020-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# SPDX-FileCopyrightText: Copyright (c) 2020-2024 NVIDIA CORPORATION & AFFILIATES -# SPDX-License-Identifier: BSD-3-Clause -################################################################################# - -import flip -import sys - -if __name__ == '__main__': - flip.execute(sys.argv) - - diff --git a/python/requirements.txt b/python/requirements.txt deleted file mode 100644 index 8248f97..0000000 --- a/python/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -matplotlib -numpy \ No newline at end of file diff --git a/python/setup.py b/setup.py similarity index 83% rename from python/setup.py rename to setup.py index e6c4200..cfb2589 100644 --- a/python/setup.py +++ b/setup.py @@ -35,7 +35,8 @@ import os import sys -__version__ = "1.4" +__package_name__ = "flip_evaluator" +__version__ = "1.5" # Separate compiler options for Windows. extra_compile_args = ["-DNDEBUG"] @@ -50,7 +51,7 @@ ext_modules = [ Pybind11Extension( "pbflip", # Name of pybind11 module. - ["flip/main.cpp"], + [__package_name__ + "/pybindFLIP.cpp"], extra_compile_args=extra_compile_args, extra_link_args=extra_link_args, cxx_std=20 @@ -63,15 +64,25 @@ # Run setup. setup( - name="flip", + name=__package_name__, version=__version__, author="NVIDIA", author_email="pandersson@nvidia.com", description="A Difference Evaluator for Alternating Images", url="https://github.com/nvlabs/flip", - license="BSD", + license="Berkeley Software Distribution (BSD) 3-Clause", + packages=[__package_name__, __package_name__ + '.cpp', __package_name__ + '.cpp.tool'], + package_data = {__package_name__: ['cpp/FLIP.h', 'cpp/tool/*.h', 'cpp/tool/.*cpp']}, + include_package_data = True, + install_requires=['numpy', 'matplotlib'], long_description=long_description, long_description_content_type='text/markdown', ext_modules=ext_modules, - python_requires=">=3.7" + python_requires=">=3.7", + + entry_points={ + 'console_scripts': [ + 'flip=' + __package_name__ + '.flip_python_api:main' + ] + } ) \ No newline at end of file From 4dbc2f489d1dee60262f7773a0aefe099831f50e Mon Sep 17 00:00:00 2001 From: pandersson94 Date: Wed, 30 Oct 2024 12:25:36 +0100 Subject: [PATCH 03/32] Update flip_ci.yml --- .github/workflows/flip_ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/flip_ci.yml b/.github/workflows/flip_ci.yml index e380ddd..7b1d802 100644 --- a/.github/workflows/flip_ci.yml +++ b/.github/workflows/flip_ci.yml @@ -24,12 +24,12 @@ jobs: - name: Configure CMake run: > - cmake -LA -B ${{github.workspace}}/build + cmake -LA -B ${{github.workspace}}/flip_evaluator/build -DCMAKE_BUILD_TYPE=${{ matrix.config }} - -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/build/install + -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/flip_evaluator/build/install -DCMAKE_CUDA_ARCHITECTURES=all -DCMAKE_CUDA_HOST_COMPILER=g++-10 -DFLIP_ENABLE_CUDA=${{ matrix.os == 'ubuntu-latest' }} - name: Build - run: cmake --build ${{github.workspace}}/build --config ${{ matrix.config }} --target install + run: cmake --build ${{github.workspace}}/flip_evaluator/build --config ${{ matrix.config }} --target install From 218e9dc75ecf0beaa068606f01f02d77c0bbf55f Mon Sep 17 00:00:00 2001 From: pandersson94 Date: Wed, 30 Oct 2024 21:57:46 +0100 Subject: [PATCH 04/32] Update flip_ci.yml --- .github/workflows/flip_ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/flip_ci.yml b/.github/workflows/flip_ci.yml index 7b1d802..3bdac02 100644 --- a/.github/workflows/flip_ci.yml +++ b/.github/workflows/flip_ci.yml @@ -32,4 +32,4 @@ jobs: -DFLIP_ENABLE_CUDA=${{ matrix.os == 'ubuntu-latest' }} - name: Build - run: cmake --build ${{github.workspace}}/flip_evaluator/build --config ${{ matrix.config }} --target install + run: cmake -B ${{github.workspace}}/flip_evaluator/build -S ${{github.workspace}}/flip_evaluator/ --build ${{github.workspace}}/flip_evaluator/build --config ${{ matrix.config }} --target install From 7d4831d9e0bd2a305b93b704f06aeae2be6ca598 Mon Sep 17 00:00:00 2001 From: pandersson94 Date: Wed, 30 Oct 2024 22:02:18 +0100 Subject: [PATCH 05/32] Update flip_ci.yml --- .github/workflows/flip_ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/flip_ci.yml b/.github/workflows/flip_ci.yml index 3bdac02..90e365a 100644 --- a/.github/workflows/flip_ci.yml +++ b/.github/workflows/flip_ci.yml @@ -24,7 +24,7 @@ jobs: - name: Configure CMake run: > - cmake -LA -B ${{github.workspace}}/flip_evaluator/build + cmake -LA -B ${{github.workspace}}/flip_evaluator/build -S ${{github.workspace}}/flip_evaluator/ -DCMAKE_BUILD_TYPE=${{ matrix.config }} -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/flip_evaluator/build/install -DCMAKE_CUDA_ARCHITECTURES=all @@ -32,4 +32,4 @@ jobs: -DFLIP_ENABLE_CUDA=${{ matrix.os == 'ubuntu-latest' }} - name: Build - run: cmake -B ${{github.workspace}}/flip_evaluator/build -S ${{github.workspace}}/flip_evaluator/ --build ${{github.workspace}}/flip_evaluator/build --config ${{ matrix.config }} --target install + run: cmake --build ${{github.workspace}}/flip_evaluator/build --config ${{ matrix.config }} --target install From 30710e4aa8ee2778332477a538ceac59fa873099 Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Thu, 31 Oct 2024 09:15:49 +0100 Subject: [PATCH 06/32] Major bugfix and couple of small changes --- flip_evaluator/cpp/FLIP.h | 2 +- flip_evaluator/pybindFLIP.cpp | 7 ++++++- setup.py | 16 ++++++++++------ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/flip_evaluator/cpp/FLIP.h b/flip_evaluator/cpp/FLIP.h index a27cdc9..232d72a 100644 --- a/flip_evaluator/cpp/FLIP.h +++ b/flip_evaluator/cpp/FLIP.h @@ -2447,7 +2447,7 @@ namespace FLIP { FLIP::image referenceImage; FLIP::image testImage; - FLIP::image errorMapFLIPOutputImage(imageWidth, imageHeight); + FLIP::image errorMapFLIPOutputImage(imageWidth, imageHeight, 0.0f); referenceImage.setPixels(referenceThreeChannelImage, imageWidth, imageHeight); testImage.setPixels(testThreeChannelImage, imageWidth, imageHeight); diff --git a/flip_evaluator/pybindFLIP.cpp b/flip_evaluator/pybindFLIP.cpp index 21af1ff..a0c5ac9 100644 --- a/flip_evaluator/pybindFLIP.cpp +++ b/flip_evaluator/pybindFLIP.cpp @@ -61,7 +61,12 @@ namespace py = pybind11; py::array_t load(std::string fileName) { FLIP::image image; - ImageHelpers::load(image, fileName); + bool imageOk = ImageHelpers::load(image, fileName); + if (!imageOk) + { + std::cout << "Error: could not read image file <" << fileName << ">. Exiting\n"; + exit(EXIT_FAILURE); + } const int imageWidth = image.getWidth(); const int imageHeight = image.getHeight(); diff --git a/setup.py b/setup.py index cfb2589..3012352 100644 --- a/setup.py +++ b/setup.py @@ -47,6 +47,10 @@ elif os.environ.get("USEOPENMP") or not sys.platform.startswith("darwin"): extra_compile_args = ["-fopenmp"] extra_link_args = ["-lgomp"] +else: # on Mac + extra_compile_args = [] + extra_link_args = [] + os.environ["MACOSX_DEPLOYMENT_TARGET"] = "10.15" # FLIP requires OS X >= 10.15. ext_modules = [ Pybind11Extension( @@ -71,18 +75,18 @@ description="A Difference Evaluator for Alternating Images", url="https://github.com/nvlabs/flip", license="Berkeley Software Distribution (BSD) 3-Clause", - packages=[__package_name__, __package_name__ + '.cpp', __package_name__ + '.cpp.tool'], - package_data = {__package_name__: ['cpp/FLIP.h', 'cpp/tool/*.h', 'cpp/tool/.*cpp']}, + packages=[__package_name__, __package_name__ + ".cpp", __package_name__ + ".cpp.tool"], + package_data = {__package_name__: ["cpp/FLIP.h", "cpp/tool/*.h", "cpp/tool/.*cpp"]}, include_package_data = True, - install_requires=['numpy', 'matplotlib'], + install_requires=["numpy", "matplotlib"], long_description=long_description, - long_description_content_type='text/markdown', + long_description_content_type="text/markdown", ext_modules=ext_modules, python_requires=">=3.7", entry_points={ - 'console_scripts': [ - 'flip=' + __package_name__ + '.flip_python_api:main' + "console_scripts": [ + "flip=" + __package_name__ + ".flip_python_api:main" ] } ) \ No newline at end of file From 7d4b7e9fea5c398ab0698f9caf380a57ff357bce Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Thu, 31 Oct 2024 10:07:23 +0100 Subject: [PATCH 07/32] Minor notes added to README and other information files --- README.md | 2 +- flip_evaluator/misc/precision.md | 9 +++++++-- flip_evaluator/misc/versionList.md | 2 +- flip_evaluator/python/README.md | 1 + 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a64c1f6..8072962 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ pip install flip-evaluator **Usage:**
API:
-See the example script `flip_evaluator/python/api_example.py`.. +See the example script `flip_evaluator/python/api_example.py`. Tool: ``` diff --git a/flip_evaluator/misc/precision.md b/flip_evaluator/misc/precision.md index 6790ac6..0d64ecf 100644 --- a/flip_evaluator/misc/precision.md +++ b/flip_evaluator/misc/precision.md @@ -6,8 +6,8 @@ to get perfect matches between the implementations. These include: 1. Our computations are made using 32-bit floating-point arithmetic. 2. The order of operations matter, with respect to the result. - * We are using functions from `numpy` and `pytorch`, and these may be implemented differently. Even computing the mean of an - array can give different results because of this. + * We are using different versions of functions in the different versions of FLIP, and these may not all use similar implementations. + Even computing the mean of an array can give different results because of this. * As an example, if a 2D filter implementation's outer loop is on `x` and the inner loop is on `y`, that will in the majority of cases give a different floating-point result compared to have the outer loop be `y` and the inner `x`. 4. GPUs attempt to try to use fused multiply-and-add (FMA) operations, i.e., `a*b+c`, as much as possible. These are faster, but the entire @@ -19,3 +19,8 @@ These include: we have therefore updated the `images/correct_{ldr|hdr}flip_{cpp|cuda}.{png|exr}` images. That said, we have tried to make the results of our different implementations as close to each other as we could. There may still be differences. + +Furthermore, the Python version of FLIP, installed using `pip install flip_evaluator`, runs on Windows, Linux (tested on Ubuntu 24.04), +and OS X ($\ge$ 10.15). However, its output sometimes differ slightly between the different operative systems. +The references used for `flip_evaluator/tests/test.py` are made for Windows. While the mean tests (means compared up to six decimal points) +pass on each mentioned operative system, not all error map pixels are identical. diff --git a/flip_evaluator/misc/versionList.md b/flip_evaluator/misc/versionList.md index 8881cbe..2b47e6e 100644 --- a/flip_evaluator/misc/versionList.md +++ b/flip_evaluator/misc/versionList.md @@ -6,8 +6,8 @@ changed for the different versions of FLIP: # Version 1.5 (commit ?) - Flipped the ꟻ in ꟻLIP. The entire name (FLIP) should now be readable on all devices. - Published Python version of FLIP to PyPI (URL: ?). - - The distribution has been tested on Windows, Linux (Ubuntu), and macOS. - The Python version of FLIP (tool and API) is now installed by `pip install flip-evaluator`. + - The distribution has been tested on Windows, Linux (Ubuntu 24.04), and OS X ($\ge$ 10.15). Note that FLIP's output might differ slightly between the different operative systems. The references used for `flip_evaluator/tests/test.py` are made for Windows. While the mean tests (means compared up to six decimal points) pass on each mentioned operative system, not all error map pixels are identical. - After installation, the tool can be run directly in a shell by `flip --reference reference.{png|exr} --test test.{png|exr}`. - After installation, the FLIP API is available in Python by `import flip_evaluator as flip`. - Directory structure in the FLIP repository has been altered to accomodate the Python version being published to PyPI. diff --git a/flip_evaluator/python/README.md b/flip_evaluator/python/README.md index 76c494e..2ec19c4 100644 --- a/flip_evaluator/python/README.md +++ b/flip_evaluator/python/README.md @@ -37,6 +37,7 @@ For business inquiries, please visit our website and submit the form: [NVIDIA Re - Usage (API): See example in the script `flip_evaluator/python/api_example.py`. - Usage (tool): `flip --reference reference.{exr|png} --test test.{exr|png} [--options]`, where the list of options can be seen by `flip -h`. - Tested with pip 24.0, Python 3.11.8, pybind11 2.11.1, and C++20. +- FLIP runs on Windows, Linux (tested on Ubuntu 24.04), and OS X ($\ge$ 10.15), though its output might differ slightly between the different operative systems. The references used for `flip_evaluator/tests/test.py` are made for Windows. While the mean tests (means compared up to six decimal points) pass for each mentioned operative system, not all error map pixels are identical. - The code that implements FLIP metrics and the FLIP tool is available in [flip_evaluator/cpp/FLIP.h](https://github.com/NVlabs/flip/blob/main/cpp/FLIP.h) and [flip_evaluator/cpp/tool](https://github.com/NVlabs/flip/blob/main/cpp/tool), respectively. The relevant functions are called by the Python API using [pybind11](https://github.com/pybind/pybind11) (see [flip_evaluator/main.cpp](https://github.com/NVlabs/flip/blob/main/flip_evaluator/main.cpp)). The Python API is provided in `flip_evaluator/main.py`. `flip_evaluator/tests/test.py` contains simple tests used to test whether code updates alter results. - Weighted histograms are output as Python scripts. Running the script will create a PDF version of the histogram. Notice that those scripts require `numpy` and `matplotlib`, both of which are automatically installed during setup. From aa88bb66f86e8288d38450937cb0b4b2ff9bed56 Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Thu, 31 Oct 2024 10:38:17 +0100 Subject: [PATCH 08/32] Re-added lost code and improved README --- README.md | 10 ++++++++++ flip_evaluator/cpp/tool/FLIPToolHelpers.h | 12 ++++++------ flip_evaluator/cpp/tool/filename.h | 6 ++++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8072962..0222ca2 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,16 @@ For individual contributions to the project, please confer the [Individual Contr For business inquiries, please visit our website and submit the form: [NVIDIA Research Licensing](https://www.nvidia.com/en-us/research/inquiries/). +# Simplest Way To Get Started +The simplest way to run FLIP to compare a test image `testImage.png` to a reference image `referenceImage.png` is as follows: +``` +pip install flip-evaluator +flip -r referenceImage.png -t testImage.png +``` +For more information about the tool's capabilities, try running `flip -h`. + +If you wish to use FLIP in your Python or C++ evaluation scripts, please read the next sections. + # Python (API and Tool) **Setup** (with pip): ``` diff --git a/flip_evaluator/cpp/tool/FLIPToolHelpers.h b/flip_evaluator/cpp/tool/FLIPToolHelpers.h index 7ba0203..4aab16f 100644 --- a/flip_evaluator/cpp/tool/FLIPToolHelpers.h +++ b/flip_evaluator/cpp/tool/FLIPToolHelpers.h @@ -239,8 +239,8 @@ namespace FLIPTool { if (intermediateLDRImages.size() > 0) { - FLIP::filename rFileName("tmp.png"); - FLIP::filename tFileName("tmp.png"); + FLIP::filename rFileName(".png"); + FLIP::filename tFileName(".png"); if (intermediateLDRImages.size() != size_t(parameters.numExposures * 2)) { std::cout << "FLIP tool error: the number of LDR images from HDR-FLIP is not the expected number.\nExiting.\n"; @@ -510,10 +510,10 @@ namespace FLIPTool bool bUseHDR = (referenceFileName.getExtension() == "exr"); std::string destinationDirectory = "."; std::string basename = (commandLine.optionSet("basename") ? commandLine.getOptionValue("basename") : ""); - FLIP::filename flipFileName("tmp.png"); // Dummy file name, but it keeps the file extension (.png). - FLIP::filename histogramFileName("tmp.py"); - FLIP::filename exposureFileName("tmp.png"); - FLIP::filename txtFileName("tmp.txt"); + FLIP::filename flipFileName(".png"); + FLIP::filename histogramFileName(".py"); + FLIP::filename exposureFileName(".png"); + FLIP::filename txtFileName(".txt"); FLIP::filename testFileName; bool returnLDRImages = false; // Can only happen for HDR. bool returnLDRFLIPImages = false; // Can only happen for HDR. diff --git a/flip_evaluator/cpp/tool/filename.h b/flip_evaluator/cpp/tool/filename.h index 2a3c32b..f0cd6f6 100644 --- a/flip_evaluator/cpp/tool/filename.h +++ b/flip_evaluator/cpp/tool/filename.h @@ -412,6 +412,12 @@ namespace FLIP bool parse(std::string path) { init(); + size_t periodCount = std::count_if(path.begin(), path.end(), [](char c) {return c == '.'; }); + if (path[0] == '.' && periodCount == 1) + { + mExtension = path.substr(1); + return true; + } // Must be at least one slash to contain a directory. size_t iLastSlash = path.find_last_of("\\/"); From bd2f1ad9590f4c0fc11f422fb966d11a80e7ff9b Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Thu, 31 Oct 2024 11:02:09 +0100 Subject: [PATCH 09/32] Added FLIP error/exposure map locations to output string --- flip_evaluator/cpp/tool/FLIPToolHelpers.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/flip_evaluator/cpp/tool/FLIPToolHelpers.h b/flip_evaluator/cpp/tool/FLIPToolHelpers.h index 4aab16f..ed66717 100644 --- a/flip_evaluator/cpp/tool/FLIPToolHelpers.h +++ b/flip_evaluator/cpp/tool/FLIPToolHelpers.h @@ -318,7 +318,8 @@ namespace FLIPTool static void gatherStatisticsAndSaveOutput(commandline& commandLine, FLIP::image& errorMapFLIP, FLIPPooling::pooling& pooledValues, const std::string& destinationDirectory, const FLIP::filename& referenceFileName, const FLIP::filename& testFileName, const FLIP::filename& histogramFileName, - const FLIP::filename& txtFileName, const std::string& FLIPString, const float time, const uint32_t testFileCount, const bool saveOverlappedHistogram, const size_t verbosity) + const FLIP::filename& txtFileName, const FLIP::filename& flipFileName, const FLIP::filename& exposureFileName, const std::string& FLIPString, const float time, + const uint32_t testFileCount, const bool saveOverlappedHistogram, const bool useHDR, const size_t verbosity) { for (int y = 0; y < errorMapFLIP.getHeight(); y++) { @@ -413,6 +414,14 @@ namespace FLIPTool std::cout << " Min: " << FIXED_DECIMAL_DIGITS(minValue, 6) << "\n"; std::cout << " Max: " << FIXED_DECIMAL_DIGITS(maxValue, 6) << "\n"; std::cout << " Evaluation time: " << FIXED_DECIMAL_DIGITS(time, 4) << " seconds\n"; + if (!commandLine.optionSet("no-error-map")) + { + std::cout << " FLIP error map location: " << destinationDirectory + "/" + flipFileName.toString() << "\n"; + } + if (!commandLine.optionSet("no-exposure-map") && useHDR) + { + std::cout << " FLIP exposure map location: " << destinationDirectory + "/" + exposureFileName.toString() << "\n"; + } std::cout << ((testFileCount < commandLine.getOptionValues("test").size()) ? "\n" : ""); } } @@ -589,7 +598,7 @@ namespace FLIPTool saveErrorAndExposureMaps(bUseHDR, commandLine, parameters, basename, errorMapFLIP, maxErrorExposureMap, destinationDirectory, referenceFileName, testFileName, histogramFileName, txtFileName, flipFileName, exposureFileName, verbosity, testFileCount); saveIntermediateHDRFLIPOutput(commandLine, parameters, basename, flipFileName, referenceFileName, testFileName, destinationDirectory, intermediateLDRFLIPImages, intermediateLDRImages); - gatherStatisticsAndSaveOutput(commandLine, errorMapFLIP, pooledValues, destinationDirectory, referenceFileName, testFileName, histogramFileName, txtFileName, FLIPString, time, ++testFileCount, saveOverlappedHistogram, verbosity); + gatherStatisticsAndSaveOutput(commandLine, errorMapFLIP, pooledValues, destinationDirectory, referenceFileName, testFileName, histogramFileName, txtFileName, flipFileName, exposureFileName, FLIPString, time, ++testFileCount, saveOverlappedHistogram, bUseHDR, verbosity); // Save first set of results for overlapped histogram. if (saveOverlappedHistogram && testFileCount == 1) From 032d51ae4b8f76c098867280cbd8063aba90f4fd Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Thu, 31 Oct 2024 11:08:28 +0100 Subject: [PATCH 10/32] Added PyPI URL to versionList.md --- flip_evaluator/misc/versionList.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flip_evaluator/misc/versionList.md b/flip_evaluator/misc/versionList.md index 2b47e6e..0e645d6 100644 --- a/flip_evaluator/misc/versionList.md +++ b/flip_evaluator/misc/versionList.md @@ -5,7 +5,7 @@ changed for the different versions of FLIP: # Version 1.5 (commit ?) - Flipped the ꟻ in ꟻLIP. The entire name (FLIP) should now be readable on all devices. -- Published Python version of FLIP to PyPI (URL: ?). +- Published Python version of FLIP to PyPI (URL: https://pypi.org/project/flip-evaluator/). - The Python version of FLIP (tool and API) is now installed by `pip install flip-evaluator`. - The distribution has been tested on Windows, Linux (Ubuntu 24.04), and OS X ($\ge$ 10.15). Note that FLIP's output might differ slightly between the different operative systems. The references used for `flip_evaluator/tests/test.py` are made for Windows. While the mean tests (means compared up to six decimal points) pass on each mentioned operative system, not all error map pixels are identical. - After installation, the tool can be run directly in a shell by `flip --reference reference.{png|exr} --test test.{png|exr}`. From 86eb71fa54df5d0e197c6175d40fc1d8585f0537 Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Thu, 31 Oct 2024 11:15:55 +0100 Subject: [PATCH 11/32] Updated Python and C++ READMEs based on new expected FLIP tool output --- flip_evaluator/cpp/README.md | 2 ++ flip_evaluator/python/README.md | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/flip_evaluator/cpp/README.md b/flip_evaluator/cpp/README.md index 02b4876..d2891f3 100644 --- a/flip_evaluator/cpp/README.md +++ b/flip_evaluator/cpp/README.md @@ -131,6 +131,8 @@ FLIP between reference image and test image : Min: 0.003123 Max: 0.962022 Evaluation time: seconds + FLIP error map location: + FLIP exposure map location: ``` where `` is the time it took to evaluate HDR-FLIP. In addition, you will now find the files `flip.reference.test.67ppd.hdr.aces.m12.5423_to_p0.9427.14.png` and `exposure_map.reference.test.67ppd.hdr.aces.m12.5423_to_p0.9427.14.png` in the directory containing the `flip[-cuda].exe` executable, and we urge you to inspect those, which will reveal where the errors in the test image are located. diff --git a/flip_evaluator/python/README.md b/flip_evaluator/python/README.md index 2ec19c4..c7cb163 100644 --- a/flip_evaluator/python/README.md +++ b/flip_evaluator/python/README.md @@ -86,7 +86,7 @@ For business inquiries, please visit our website and submit the form: [NVIDIA Re Text file: `.txt`
**Example usage:** -To test the API, please inspect the `flip_evaluator/python/api_example.py` script. This shows how the available API commands may be used. Note that the script requires `matplotlib`. +To test the API, please inspect the `flip_evaluator/python/api_example.py` script. This shows how the available API commands may be used. Please note that not all capabilities of the tool is available through the Python API. For example, the exposure map is not output when running HDR-FLIP. For that, use the tool or the C++ API in [FLIP.h](https://github.com/NVlabs/flip/blob/main/cpp/FLIP.h). To test the tool, start a shell, navigate to `flip_evaluator/python` and try: @@ -110,6 +110,8 @@ FLIP between reference image and test image : Min: 0.003123 Max: 0.962022 Evaluation time: seconds + FLIP error map location: + FLIP exposure map location: ``` where `` is the time it took to evaluate HDR-FLIP. In addition, you will now find the files `flip.reference.test.67ppd.hdr.aces.m12.5423_to_p0.9427.14.png` and `exposure_map.reference.test.67ppd.hdr.aces.m12.5423_to_p0.9427.14.png` in the working directory, and we urge you to inspect those, which will reveal where the errors in the test image are located. From 0a252dbfcad226c3c19c22ab741241fc2c1c895e Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Thu, 31 Oct 2024 15:16:10 +0100 Subject: [PATCH 12/32] Updated README links --- README.md | 26 +++++++++++++------------- flip_evaluator/cpp/README.md | 12 ++++++------ flip_evaluator/python/README.md | 12 ++++++------ flip_evaluator/pytorch/README.md | 8 ++++---- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 0222ca2..c3b31b6 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,11 @@ This repository holds implementations of the [LDR-FLIP](https://research.nvidia. and [HDR-FLIP](https://research.nvidia.com/publication/2021-05_HDR-FLIP) image error metrics. It also holds code for the FLIP tool, presented in [Ray Tracing Gems II](https://www.realtimerendering.com/raytracinggems/rtg2/index.html). -The changes made for the different versions of FLIP are summarized in the [version list](misc/versionList.md). +The changes made for the different versions of FLIP are summarized in the [version list](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/versionList.md). -[A list of papers](flip_evaluator/misc/papersUsingFLIP.md) that use/cite FLIP. +[A list of papers](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/papersUsingFLIP.md) that use/cite FLIP. -[A note](flip_evaluator/misc/precision.md) about the precision of FLIP. +[A note](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/precision.md) about the precision of FLIP. [An image gallery](https://research.nvidia.com/node/3525) displaying a large quantity of reference/test images and corresponding error maps from different metrics. @@ -37,10 +37,10 @@ Copyright © 2020-2024, NVIDIA Corporation & Affiliates. All rights reserved. This work is made available under a [BSD 3-Clause License](LICENSE). -The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](flip_evaluator/misc/LICENSE-third-party.md#bsd-3-clause-license),
-and `stb_image`, which is subject to an [MIT License](flip_evaluator/misc/LICENSE-third-party.md#mit-license). +The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#bsd-3-clause-license),
+and `stb_image`, which is subject to an [MIT License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#mit-license). -For individual contributions to the project, please confer the [Individual Contributor License Agreement](flip_evaluator/misc/CLA.md). +For individual contributions to the project, please confer the [Individual Contributor License Agreement](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/CLA.md). For business inquiries, please visit our website and submit the form: [NVIDIA Research Licensing](https://www.nvidia.com/en-us/research/inquiries/). @@ -70,7 +70,7 @@ Tool: flip --reference reference.{exr|png} --test test.{exr|png} [--options] ``` -See the [README](flip_evaluator/python/README.md) in the `python` folder and run `flip -h` for further information and usage instructions. +See the [README](https://github.com/NVlabs/flip/blob/main/flip_evaluator/python/README.md) in the `python` folder and run `flip -h` for further information and usage instructions. # C++ and CUDA (API and Tool) **Setup:** @@ -95,14 +95,14 @@ CUDA support is enabled via the `FLIP_ENABLE_CUDA`, which can be passed to CMake **Usage:**
API:
-See the [README](flip_evaluator/cpp/README.md). +See the [README](https://github.com/NVlabs/flip/blob/main/flip_evaluator/cpp/README.md). Tool: ``` flip[-cuda].exe --reference reference.{exr|png} --test test.{exr|png} [options] ``` -See the [README](flip_evaluator/cpp/README.md) in the `flip_evaluator/cpp` folder and run `flip[-cuda].exe -h` for further information and usage instructions. +See the [README](https://github.com/NVlabs/flip/blob/main/flip_evaluator/cpp/README.md) in the `flip_evaluator/cpp` folder and run `flip[-cuda].exe -h` for further information and usage instructions. # PyTorch (Loss Function) **Setup** (with Anaconda3 or Miniconda): @@ -119,19 +119,19 @@ conda install -c conda-forge openexr-python LDR- and HDR-FLIP are implemented as loss modules in `flip_evaluator/pytorch/flip_loss.py`. An example where the loss function is used to train a simple autoencoder is provided in `flip_evaluator/pytorch/train.py`. -See the [README](flip_evaluator/pytorch/README.md) in the `pytorch` folder for further information and usage instructions. +See the [README](https://github.com/NVlabs/flip/blob/main/flip_evaluator/pytorch/README.md) in the `pytorch` folder for further information and usage instructions. # Citation If your work uses the FLIP tool to find the errors between *low dynamic range* images, please cite the LDR-FLIP paper:
-[Paper](https://research.nvidia.com/publication/2020-07_FLIP) | [BibTeX](flip_evaluator/misc/LDRFLIP.txt) +[Paper](https://research.nvidia.com/publication/2020-07_FLIP) | [BibTeX](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LDRFLIP.txt) If it uses the FLIP tool to find the errors between *high dynamic range* images, instead cite the HDR-FLIP paper:
-[Paper](https://research.nvidia.com/publication/2021-05_HDR-FLIP) | [BibTeX](flip_evaluator/misc/HDRFLIP.txt) +[Paper](https://research.nvidia.com/publication/2021-05_HDR-FLIP) | [BibTeX](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/HDRFLIP.txt) Should your work use the FLIP tool in a more general fashion, please cite the Ray Tracing Gems II article:
-[Chapter](https://link.springer.com/chapter/10.1007%2F978-1-4842-7185-8_19) | [BibTeX](flip_evaluator/misc/FLIP.txt) +[Chapter](https://link.springer.com/chapter/10.1007%2F978-1-4842-7185-8_19) | [BibTeX](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/FLIP.txt) # Acknowledgements We appreciate the following peoples' contributions to this repository: diff --git a/flip_evaluator/cpp/README.md b/flip_evaluator/cpp/README.md index d2891f3..197e6dd 100644 --- a/flip_evaluator/cpp/README.md +++ b/flip_evaluator/cpp/README.md @@ -17,7 +17,7 @@ and [HDR-FLIP](https://research.nvidia.com/publication/2021-05_HDR-FLIP) image e It also holds code for the FLIP tool, presented in [Ray Tracing Gems II](https://www.realtimerendering.com/raytracinggems/rtg2/index.html). Note that since v1.2, we use separated convolutions for the C++ and CUDA versions of FLIP. A note explaining those -can be found [here](misc/separatedConvolutions.pdf). +can be found [here](https://github.com/NVlabs/flip/blob/main/misc/separatedConvolutions.pdf). With v1.3, we have switched to a single header [FLIP.h](FLIP.h) for easier integration into other projects. @@ -28,12 +28,12 @@ Since v1.4, the majority of the code for the tool is contained in [FLIPToolHelpe Copyright © 2020-2024, NVIDIA Corporation & Affiliates. All rights reserved. -This work is made available under a [BSD 3-Clause License](../../LICENSE). +This work is made available under a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/LICENSE). -The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](../misc/LICENSE-third-party.md#bsd-3-clause-license),
-and `stb_image`, which is subject to an [MIT License](../misc/LICENSE-third-party.md#mit-license). +The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#bsd-3-clause-license),
+and `stb_image`, which is subject to an [MIT License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#mit-license). -For individual contributions to the project, please confer the [Individual Contributor License Agreement](../misc/CLA.md). +For individual contributions to the project, please confer the [Individual Contributor License Agreement](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/CLA.md). For business inquiries, please visit our website and submit the form: [NVIDIA Research Licensing](https://www.nvidia.com/en-us/research/inquiries/). @@ -64,7 +64,7 @@ For business inquiries, please visit our website and submit the form: [NVIDIA Re - Usage: `flip[-cuda].exe --reference reference.{exr|png} --test test.{exr|png} [options]`, where the list of options can be seen by `flip[-cuda].exe -h`. - Tested on Windows 10 version 22H2 and Windows 11 version 23H2 with CUDA 12.3. Compiled with Visual Studio 2022. If you use another version of CUDA, you will need to change the `CUDA 12.3` strings in the `CUDA.vcxproj` file accordingly. - `flip_evaluator/tests/test.py` contains simple tests used to test whether code updates alter results. -- Weighted histograms are output as Python scripts. Running the script will create a PDF version of the histogram. Notice that those scripts require `numpy` and `matplotlib`, both of which may be installed using pip. These are automantically installed when installing the Python version of FLIP (see [README.md](../python/README.md)). +- Weighted histograms are output as Python scripts. Running the script will create a PDF version of the histogram. Notice that those scripts require `numpy` and `matplotlib`, both of which may be installed using pip. These are automantically installed when installing the Python version of FLIP (see [README.md](https://github.com/NVlabs/flip/blob/main/flip_evaluator/python/README.md)). - The naming convention used for the FLIP tool's output is as follows (where `ppd` is the assumed number of pixels per degree, `tm` is the tone mapper assumed by HDR-FLIP, `cstart` and `cstop` are the shortest and longest exposures, respectively, assumed by HDR-FLIP, with `p` indicating a positive value and `m` indicating a negative value, diff --git a/flip_evaluator/python/README.md b/flip_evaluator/python/README.md index c7cb163..486c781 100644 --- a/flip_evaluator/python/README.md +++ b/flip_evaluator/python/README.md @@ -20,12 +20,12 @@ Similarly, it implements the FLIP tool, presented in [Ray Tracing Gems II](https Copyright © 2020-2024, NVIDIA Corporation & Affiliates. All rights reserved. -This work is made available under a [BSD 3-Clause License](../../LICENSE). +This work is made available under a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/LICENSE). -The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](../misc/LICENSE-third-party.md#bsd-3-clause-license),
-and `stb_image`, which is subject to an [MIT License](../misc/LICENSE-third-party.md#mit-license). +The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#bsd-3-clause-license),
+and `stb_image`, which is subject to an [MIT License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#mit-license). -For individual contributions to the project, please confer the [Individual Contributor License Agreement](../misc/CLA.md). +For individual contributions to the project, please confer the [Individual Contributor License Agreement](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/CLA.md). For business inquiries, please visit our website and submit the form: [NVIDIA Research Licensing](https://www.nvidia.com/en-us/research/inquiries/). @@ -38,7 +38,7 @@ For business inquiries, please visit our website and submit the form: [NVIDIA Re - Usage (tool): `flip --reference reference.{exr|png} --test test.{exr|png} [--options]`, where the list of options can be seen by `flip -h`. - Tested with pip 24.0, Python 3.11.8, pybind11 2.11.1, and C++20. - FLIP runs on Windows, Linux (tested on Ubuntu 24.04), and OS X ($\ge$ 10.15), though its output might differ slightly between the different operative systems. The references used for `flip_evaluator/tests/test.py` are made for Windows. While the mean tests (means compared up to six decimal points) pass for each mentioned operative system, not all error map pixels are identical. -- The code that implements FLIP metrics and the FLIP tool is available in [flip_evaluator/cpp/FLIP.h](https://github.com/NVlabs/flip/blob/main/cpp/FLIP.h) and [flip_evaluator/cpp/tool](https://github.com/NVlabs/flip/blob/main/cpp/tool), respectively. The relevant functions are called by the Python API using [pybind11](https://github.com/pybind/pybind11) (see [flip_evaluator/main.cpp](https://github.com/NVlabs/flip/blob/main/flip_evaluator/main.cpp)). The Python API is provided in `flip_evaluator/main.py`. +- The code that implements FLIP metrics and the FLIP tool is available in [flip_evaluator/cpp/FLIP.h](https://github.com/NVlabs/flip/blob/main/flip_evaluator/cpp/FLIP.h) and [flip_evaluator/cpp/tool](https://github.com/NVlabs/flip/blob/main/flip_evaluator/cpp/tool), respectively. The relevant functions are called by the Python API using [pybind11](https://github.com/pybind/pybind11) (see [flip_evaluator/main.cpp](https://github.com/NVlabs/flip/blob/main/flip_evaluator/main.cpp)). The Python API is provided in `flip_evaluator/main.py`. `flip_evaluator/tests/test.py` contains simple tests used to test whether code updates alter results. - Weighted histograms are output as Python scripts. Running the script will create a PDF version of the histogram. Notice that those scripts require `numpy` and `matplotlib`, both of which are automatically installed during setup. - The naming convention used for the FLIP tool's output is as follows (where `ppd` is the assumed number of pixels per degree, @@ -87,7 +87,7 @@ For business inquiries, please visit our website and submit the form: [NVIDIA Re **Example usage:** To test the API, please inspect the `flip_evaluator/python/api_example.py` script. This shows how the available API commands may be used. -Please note that not all capabilities of the tool is available through the Python API. For example, the exposure map is not output when running HDR-FLIP. For that, use the tool or the C++ API in [FLIP.h](https://github.com/NVlabs/flip/blob/main/cpp/FLIP.h). +Please note that not all capabilities of the tool is available through the Python API. For example, the exposure map is not output when running HDR-FLIP. For that, use the tool or the C++ API in [FLIP.h](https://github.com/NVlabs/flip/blob/main/flip_evaluator/cpp/FLIP.h). To test the tool, start a shell, navigate to `flip_evaluator/python` and try: ``` diff --git a/flip_evaluator/pytorch/README.md b/flip_evaluator/pytorch/README.md index 05e6162..8cf8765 100644 --- a/flip_evaluator/pytorch/README.md +++ b/flip_evaluator/pytorch/README.md @@ -19,12 +19,12 @@ and [HDR-FLIP](https://research.nvidia.com/publication/2021-05_HDR-FLIP) image e Copyright © 2020-2024, NVIDIA Corporation & Affiliates. All rights reserved. -This work is made available under a [BSD 3-Clause License](../../LICENSE). +This work is made available under a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/LICENSE). -The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](../misc/LICENSE-third-party.md#bsd-3-clause-license),
-and `stb_image`, which is subject to an [MIT License](../misc/LICENSE-third-party.md#mit-license). +The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#bsd-3-clause-license),
+and `stb_image`, which is subject to an [MIT License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#mit-license). -For individual contributions to the project, please confer the [Individual Contributor License Agreement](../misc/CLA.md). +For individual contributions to the project, please confer the [Individual Contributor License Agreement](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/CLA.md). For business inquiries, please visit our website and submit the form: [NVIDIA Research Licensing](https://www.nvidia.com/en-us/research/inquiries/). From 8144bd5b83029c1ffa2f4c3b30b5a7e86c8285c3 Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Fri, 8 Nov 2024 12:36:21 +0100 Subject: [PATCH 13/32] Switch to nanobind and add cibuildwheel action --- .github/workflows/flip-deploy.yml | 48 ++++++ CMakeLists.txt | 89 ++++++++++ README.md | 2 +- .../images => images}/reference.exr | Bin .../images => images}/reference.png | Bin {flip_evaluator/images => images}/teaser.png | Bin {flip_evaluator/images => images}/test.exr | Bin {flip_evaluator/images => images}/test.png | Bin {flip_evaluator/misc => misc}/CLA.md | 0 {flip_evaluator/misc => misc}/FLIP.txt | 0 {flip_evaluator/misc => misc}/HDRFLIP.txt | 0 {flip_evaluator/misc => misc}/LDRFLIP.txt | 0 .../misc => misc}/LICENSE-third-party.md | 0 .../misc => misc}/papersUsingFLIP.md | 0 {flip_evaluator/misc => misc}/precision.md | 0 .../misc => misc}/separatedConvolutions.pdf | Bin {flip_evaluator/misc => misc}/versionList.md | 7 +- pyproject.toml | 43 ++++- setup.py | 92 ---------- {flip_evaluator => src}/CMakeLists.txt | 0 .../cmake/FLIPConfig.cmake | 0 {flip_evaluator => src}/cpp/CMakeLists.txt | 0 {flip_evaluator => src}/cpp/FLIP.h | 0 {flip_evaluator => src}/cpp/FLIP.sln | 0 {flip_evaluator => src}/cpp/README.md | 6 +- .../cpp/tool/CMakeLists.txt | 0 {flip_evaluator => src}/cpp/tool/CPP.vcxproj | 0 .../cpp/tool/CPP.vcxproj.filters | 0 {flip_evaluator => src}/cpp/tool/CUDA.vcxproj | 4 +- .../cpp/tool/CUDA.vcxproj.filters | 0 .../cpp/tool/FLIP-tool.cpp | 0 {flip_evaluator => src}/cpp/tool/FLIP-tool.cu | 0 .../cpp/tool/FLIPToolHelpers.h | 4 +- .../cpp/tool/commandline.h | 0 {flip_evaluator => src}/cpp/tool/filename.h | 0 .../cpp/tool/imagehelpers.h | 0 {flip_evaluator => src}/cpp/tool/pooling.h | 0 {flip_evaluator => src}/cpp/tool/stb_image.h | 0 .../cpp/tool/stb_image_write.h | 0 {flip_evaluator => src}/cpp/tool/tinyexr.h | 0 .../flip_evaluator}/__init__.py | 0 .../flip_evaluator}/flip_python_api.py | 6 +- .../pybindFLIP.cpp => src/nanobindFLIP.cpp | 158 +++++++++--------- {flip_evaluator => src}/python/README.md | 6 +- {flip_evaluator => src}/python/api_example.py | 0 {flip_evaluator => src}/pytorch/README.md | 0 {flip_evaluator => src}/pytorch/data.py | 0 {flip_evaluator => src}/pytorch/flip_loss.py | 0 {flip_evaluator => src}/pytorch/train.py | 0 .../tests/correct_hdrflip_cpp.png | Bin .../tests/correct_hdrflip_cuda.png | Bin .../tests/correct_ldrflip_cpp.png | Bin .../tests/correct_ldrflip_cuda.png | Bin {flip_evaluator => src}/tests/test.py | 18 +- {flip_evaluator => src}/tests/test_pytorch.py | 8 +- 55 files changed, 284 insertions(+), 207 deletions(-) create mode 100644 .github/workflows/flip-deploy.yml create mode 100644 CMakeLists.txt rename {flip_evaluator/images => images}/reference.exr (100%) rename {flip_evaluator/images => images}/reference.png (100%) rename {flip_evaluator/images => images}/teaser.png (100%) rename {flip_evaluator/images => images}/test.exr (100%) rename {flip_evaluator/images => images}/test.png (100%) rename {flip_evaluator/misc => misc}/CLA.md (100%) rename {flip_evaluator/misc => misc}/FLIP.txt (100%) rename {flip_evaluator/misc => misc}/HDRFLIP.txt (100%) rename {flip_evaluator/misc => misc}/LDRFLIP.txt (100%) rename {flip_evaluator/misc => misc}/LICENSE-third-party.md (100%) rename {flip_evaluator/misc => misc}/papersUsingFLIP.md (100%) rename {flip_evaluator/misc => misc}/precision.md (100%) rename {flip_evaluator/misc => misc}/separatedConvolutions.pdf (100%) rename {flip_evaluator/misc => misc}/versionList.md (87%) delete mode 100644 setup.py rename {flip_evaluator => src}/CMakeLists.txt (100%) rename {flip_evaluator => src}/cmake/FLIPConfig.cmake (100%) rename {flip_evaluator => src}/cpp/CMakeLists.txt (100%) rename {flip_evaluator => src}/cpp/FLIP.h (100%) rename {flip_evaluator => src}/cpp/FLIP.sln (100%) rename {flip_evaluator => src}/cpp/README.md (94%) rename {flip_evaluator => src}/cpp/tool/CMakeLists.txt (100%) rename {flip_evaluator => src}/cpp/tool/CPP.vcxproj (100%) rename {flip_evaluator => src}/cpp/tool/CPP.vcxproj.filters (100%) rename {flip_evaluator => src}/cpp/tool/CUDA.vcxproj (99%) rename {flip_evaluator => src}/cpp/tool/CUDA.vcxproj.filters (100%) rename {flip_evaluator => src}/cpp/tool/FLIP-tool.cpp (100%) rename {flip_evaluator => src}/cpp/tool/FLIP-tool.cu (100%) rename {flip_evaluator => src}/cpp/tool/FLIPToolHelpers.h (99%) rename {flip_evaluator => src}/cpp/tool/commandline.h (100%) rename {flip_evaluator => src}/cpp/tool/filename.h (100%) rename {flip_evaluator => src}/cpp/tool/imagehelpers.h (100%) rename {flip_evaluator => src}/cpp/tool/pooling.h (100%) rename {flip_evaluator => src}/cpp/tool/stb_image.h (100%) rename {flip_evaluator => src}/cpp/tool/stb_image_write.h (100%) rename {flip_evaluator => src}/cpp/tool/tinyexr.h (100%) rename {flip_evaluator => src/flip_evaluator}/__init__.py (100%) rename {flip_evaluator => src/flip_evaluator}/flip_python_api.py (96%) rename flip_evaluator/pybindFLIP.cpp => src/nanobindFLIP.cpp (63%) rename {flip_evaluator => src}/python/README.md (95%) rename {flip_evaluator => src}/python/api_example.py (100%) rename {flip_evaluator => src}/pytorch/README.md (100%) rename {flip_evaluator => src}/pytorch/data.py (100%) rename {flip_evaluator => src}/pytorch/flip_loss.py (100%) rename {flip_evaluator => src}/pytorch/train.py (100%) rename {flip_evaluator => src}/tests/correct_hdrflip_cpp.png (100%) rename {flip_evaluator => src}/tests/correct_hdrflip_cuda.png (100%) rename {flip_evaluator => src}/tests/correct_ldrflip_cpp.png (100%) rename {flip_evaluator => src}/tests/correct_ldrflip_cuda.png (100%) rename {flip_evaluator => src}/tests/test.py (89%) rename {flip_evaluator => src}/tests/test_pytorch.py (94%) diff --git a/.github/workflows/flip-deploy.yml b/.github/workflows/flip-deploy.yml new file mode 100644 index 0000000..6e7d5ed --- /dev/null +++ b/.github/workflows/flip-deploy.yml @@ -0,0 +1,48 @@ +# Source: https://github.com/pypa/cibuildwheel/blob/main/examples/github-deploy.yml. + +name: Build and upload to PyPI + +on: + workflow_dispatch: + pull_request: + push: + branches: + - main + release: + types: + - published + +jobs: + build_wheels: + name: Build wheels on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + # macos-13 is an intel runner, macos-14 is apple silicon + os: [ubuntu-latest, windows-latest, macos-13, macos-14] + python: [cp38, cp39, cp310, cp311, cp312, cp313] + + steps: + - uses: actions/checkout@v4 + + - name: Build wheels + uses: pypa/cibuildwheel@v2.21.3 + + - uses: actions/upload-artifact@v4 + with: + name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} + path: ./wheelhouse/*.whl + + build_sdist: + name: Build source distribution + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Build sdist + run: pipx run build --sdist + + - uses: actions/upload-artifact@v4 + with: + name: cibw-sdist + path: dist/*.tar.gz \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ea1985e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,89 @@ +################################################################################# +# Copyright (c) 2020-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# SPDX-FileCopyrightText: Copyright (c) 2020-2024 NVIDIA CORPORATION & AFFILIATES +# SPDX-License-Identifier: BSD-3-Clause +################################################################################# + +cmake_minimum_required(VERSION 3.15...3.27) +project(flip_evaluator LANGUAGES CXX) + +# Warn if the user invokes CMake directly +if (NOT SKBUILD) + message(WARNING "\ + This CMake file is meant to be executed using 'scikit-build-core'. + Running it directly will almost certainly not produce the desired + result. If you are a user trying to install this package, use the + command below, which will install all necessary build dependencies, + compile the package in an isolated environment, and then install it. + ===================================================================== + $ pip install . + ===================================================================== + If you are a software developer, and this is your own package, then + it is usually much more efficient to install the build dependencies + in your environment once and use the following command that avoids + a costly creation of a new virtual environment at every compilation: + ===================================================================== + $ pip install nanobind scikit-build-core[pyproject] + $ pip install --no-build-isolation -ve . + ===================================================================== + You may optionally add -Ceditable.rebuild=true to auto-rebuild when + the package is imported. Otherwise, you need to rerun the above + after editing C++ files.") +endif() + +if (CMAKE_VERSION VERSION_LESS 3.18) + set(DEV_MODULE Development) +else() + set(DEV_MODULE Development.Module) +endif() + +if(MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -openmp") +elseif(UNIX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgomp") +endif() + +find_package(Python 3.8 + REQUIRED COMPONENTS Interpreter Development.Module + OPTIONAL_COMPONENTS Development.SABIModule) + +if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") +endif() + +execute_process( + COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir + OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE nanobind_ROOT) +find_package(nanobind CONFIG REQUIRED) + +nanobind_add_module(pbflip STABLE_ABI src/nanobindflip.cpp) + +install(TARGETS pbflip LIBRARY DESTINATION flip_evaluator) diff --git a/README.md b/README.md index c3b31b6..f5e2b47 100644 --- a/README.md +++ b/README.md @@ -135,4 +135,4 @@ Should your work use the FLIP tool in a more general fashion, please cite the Ra # Acknowledgements We appreciate the following peoples' contributions to this repository: -Jonathan Granskog, Jacob Munkberg, Jon Hasselgren, Jefferson Amstutz, Alan Wolfe, Killian Herveau, Vinh Truong, Philippe Dagobert, Hannes Hergeth, Matt Pharr, Tizian Zeltner, Jan Honsbrok, and Chris Zhang. +Jonathan Granskog, Jacob Munkberg, Jon Hasselgren, Jefferson Amstutz, Alan Wolfe, Killian Herveau, Vinh Truong, Philippe Dagobert, Hannes Hergeth, Matt Pharr, Tizian Zeltner, Jan Honsbrok, Chris Zhang, and Wenzel Jakob. diff --git a/flip_evaluator/images/reference.exr b/images/reference.exr similarity index 100% rename from flip_evaluator/images/reference.exr rename to images/reference.exr diff --git a/flip_evaluator/images/reference.png b/images/reference.png similarity index 100% rename from flip_evaluator/images/reference.png rename to images/reference.png diff --git a/flip_evaluator/images/teaser.png b/images/teaser.png similarity index 100% rename from flip_evaluator/images/teaser.png rename to images/teaser.png diff --git a/flip_evaluator/images/test.exr b/images/test.exr similarity index 100% rename from flip_evaluator/images/test.exr rename to images/test.exr diff --git a/flip_evaluator/images/test.png b/images/test.png similarity index 100% rename from flip_evaluator/images/test.png rename to images/test.png diff --git a/flip_evaluator/misc/CLA.md b/misc/CLA.md similarity index 100% rename from flip_evaluator/misc/CLA.md rename to misc/CLA.md diff --git a/flip_evaluator/misc/FLIP.txt b/misc/FLIP.txt similarity index 100% rename from flip_evaluator/misc/FLIP.txt rename to misc/FLIP.txt diff --git a/flip_evaluator/misc/HDRFLIP.txt b/misc/HDRFLIP.txt similarity index 100% rename from flip_evaluator/misc/HDRFLIP.txt rename to misc/HDRFLIP.txt diff --git a/flip_evaluator/misc/LDRFLIP.txt b/misc/LDRFLIP.txt similarity index 100% rename from flip_evaluator/misc/LDRFLIP.txt rename to misc/LDRFLIP.txt diff --git a/flip_evaluator/misc/LICENSE-third-party.md b/misc/LICENSE-third-party.md similarity index 100% rename from flip_evaluator/misc/LICENSE-third-party.md rename to misc/LICENSE-third-party.md diff --git a/flip_evaluator/misc/papersUsingFLIP.md b/misc/papersUsingFLIP.md similarity index 100% rename from flip_evaluator/misc/papersUsingFLIP.md rename to misc/papersUsingFLIP.md diff --git a/flip_evaluator/misc/precision.md b/misc/precision.md similarity index 100% rename from flip_evaluator/misc/precision.md rename to misc/precision.md diff --git a/flip_evaluator/misc/separatedConvolutions.pdf b/misc/separatedConvolutions.pdf similarity index 100% rename from flip_evaluator/misc/separatedConvolutions.pdf rename to misc/separatedConvolutions.pdf diff --git a/flip_evaluator/misc/versionList.md b/misc/versionList.md similarity index 87% rename from flip_evaluator/misc/versionList.md rename to misc/versionList.md index 0e645d6..fa366dd 100644 --- a/flip_evaluator/misc/versionList.md +++ b/misc/versionList.md @@ -7,12 +7,13 @@ changed for the different versions of FLIP: - Flipped the ꟻ in ꟻLIP. The entire name (FLIP) should now be readable on all devices. - Published Python version of FLIP to PyPI (URL: https://pypi.org/project/flip-evaluator/). - The Python version of FLIP (tool and API) is now installed by `pip install flip-evaluator`. - - The distribution has been tested on Windows, Linux (Ubuntu 24.04), and OS X ($\ge$ 10.15). Note that FLIP's output might differ slightly between the different operative systems. The references used for `flip_evaluator/tests/test.py` are made for Windows. While the mean tests (means compared up to six decimal points) pass on each mentioned operative system, not all error map pixels are identical. + - The distribution has been tested on Windows, Linux (Ubuntu 24.04), and OS X ($\ge$ 10.15). Wheels are built for each (and various CPython versions $\ge$ 3.8) using [cibuildwheel](https://github.com/pypa/cibuildwheel). Note that FLIP's output might differ slightly between the different operative systems. The references used for `flip_evaluator/tests/test.py` are made for Windows. While the mean tests (means compared up to six decimal points) pass on each mentioned operative system, not all error map pixels are identical. - After installation, the tool can be run directly in a shell by `flip --reference reference.{png|exr} --test test.{png|exr}`. - After installation, the FLIP API is available in Python by `import flip_evaluator as flip`. -- Directory structure in the FLIP repository has been altered to accomodate the Python version being published to PyPI. +- Python version is now built using `scikit` instead of `setuptools`, and uses [nanobind](https://github.com/wjakob/nanobind) instead of [pybind11](https://github.com/pybind/pybind11). +- Directory structure in the FLIP repository has been slightly altered to accomodate the Python version being published to PyPI. - Updated Python/C++/CUDA test script. -- Various bugfixes. +- Various significant bugfixes. # Version 1.4 (commits 6265f80 to 0349494) - Changed the Python version of FLIP so that it leverages the C++ code through [pybind11](https://github.com/pybind/pybind11). diff --git a/pyproject.toml b/pyproject.toml index 8155b5f..5bef361 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,10 +31,45 @@ ################################################################################# [build-system] -requires = [ - "setuptools", "pybind11>=2.10.1" -] +requires = ["scikit-build-core >=0.4.3", "nanobind >=1.3.2"] +build-backend = "scikit_build_core.build" [project] name = "flip_evaluator" -dynamic = ['version', 'description', 'readme', 'requires-python', 'license', 'authors', 'scripts', 'dependencies'] \ No newline at end of file +version = "1.5.5" +description = "A Difference Evaluator for Alternating Images" +readme = "README.md" +requires-python = ">=3.8" +authors = [ + { name = "Pontus Ebelin" }, + { name = "Tomas Akenine-Möller" } +] +classifiers = [ + "License :: OSI Approved :: BSD License" +] + +[project.scripts] +flip = "flip_evaluator.flip_python_api:main" + +[project.urls] +Homepage = "https://github.com/nvlabs/flip" + +[tool.cibuildwheel] +build-verbosity = 1 +build = ["cp38-*", "cp39-*", "cp310-*", "cp311-*", "cp312-*", "cp313-*"] +test-command = ["flip -h"] + +[tool.cibuildwheel.macos.environment] +MACOSX_DEPLOYMENT_TARGET = "10.15" + +[tool.scikit-build] +minimum-version = "0.4" +sdist.include = ["src/flip_evaluator/__init__.py", "src/flip_evaluator/flip_python_api.py", "src/cpp/FLIP.h", "src/cpp/tool/*.h"] +sdist.exclude = [".github", ".gitignore", "images", "misc", "dist", "*__pycache__*", "src/pytorch", "src/cmake", "src/tests", "src/CMakeLists.txt", "src/flip_evaluator/api_example.py", "src/flip_evaluator/README.md", "src/cpp/FLIP.sln", "src/cpp/CMakeLists.txt", "src/cpp/README.md", "src/cpp/tool/CMakeLists.txt", "src/cpp/tool/CPP.vcxproj*", "src/cpp/tool/CUDA.vcxproj*", "src/cpp/tool/*.cpp", "src/cpp/tool/*.cu"] + +[tool.hatch.metadata.hooks.fancy-pypi-readme] +content-type = "text/markdown" + +build-dir = "build/{wheel_tag}" + +wheel.py-api = "cp312" \ No newline at end of file diff --git a/setup.py b/setup.py deleted file mode 100644 index 3012352..0000000 --- a/setup.py +++ /dev/null @@ -1,92 +0,0 @@ -################################################################################# -# Copyright (c) 2020-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# SPDX-FileCopyrightText: Copyright (c) 2020-2024 NVIDIA CORPORATION & AFFILIATES -# SPDX-License-Identifier: BSD-3-Clause -################################################################################# - -from pybind11.setup_helpers import Pybind11Extension -from setuptools import setup -import os -import sys - -__package_name__ = "flip_evaluator" -__version__ = "1.5" - -# Separate compiler options for Windows. -extra_compile_args = ["-DNDEBUG"] -if sys.platform.startswith("win"): - extra_compile_args = ["-openmp"] - extra_link_args = [] -# Use OpenMP if environment variable is set or not on a Mac. -elif os.environ.get("USEOPENMP") or not sys.platform.startswith("darwin"): - extra_compile_args = ["-fopenmp"] - extra_link_args = ["-lgomp"] -else: # on Mac - extra_compile_args = [] - extra_link_args = [] - os.environ["MACOSX_DEPLOYMENT_TARGET"] = "10.15" # FLIP requires OS X >= 10.15. - -ext_modules = [ - Pybind11Extension( - "pbflip", # Name of pybind11 module. - [__package_name__ + "/pybindFLIP.cpp"], - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - cxx_std=20 - ), -] - -# Get description from README. -with open(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'README.md'), encoding='utf-8') as f: - long_description = f.read() - -# Run setup. -setup( - name=__package_name__, - version=__version__, - author="NVIDIA", - author_email="pandersson@nvidia.com", - description="A Difference Evaluator for Alternating Images", - url="https://github.com/nvlabs/flip", - license="Berkeley Software Distribution (BSD) 3-Clause", - packages=[__package_name__, __package_name__ + ".cpp", __package_name__ + ".cpp.tool"], - package_data = {__package_name__: ["cpp/FLIP.h", "cpp/tool/*.h", "cpp/tool/.*cpp"]}, - include_package_data = True, - install_requires=["numpy", "matplotlib"], - long_description=long_description, - long_description_content_type="text/markdown", - ext_modules=ext_modules, - python_requires=">=3.7", - - entry_points={ - "console_scripts": [ - "flip=" + __package_name__ + ".flip_python_api:main" - ] - } -) \ No newline at end of file diff --git a/flip_evaluator/CMakeLists.txt b/src/CMakeLists.txt similarity index 100% rename from flip_evaluator/CMakeLists.txt rename to src/CMakeLists.txt diff --git a/flip_evaluator/cmake/FLIPConfig.cmake b/src/cmake/FLIPConfig.cmake similarity index 100% rename from flip_evaluator/cmake/FLIPConfig.cmake rename to src/cmake/FLIPConfig.cmake diff --git a/flip_evaluator/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt similarity index 100% rename from flip_evaluator/cpp/CMakeLists.txt rename to src/cpp/CMakeLists.txt diff --git a/flip_evaluator/cpp/FLIP.h b/src/cpp/FLIP.h similarity index 100% rename from flip_evaluator/cpp/FLIP.h rename to src/cpp/FLIP.h diff --git a/flip_evaluator/cpp/FLIP.sln b/src/cpp/FLIP.sln similarity index 100% rename from flip_evaluator/cpp/FLIP.sln rename to src/cpp/FLIP.sln diff --git a/flip_evaluator/cpp/README.md b/src/cpp/README.md similarity index 94% rename from flip_evaluator/cpp/README.md rename to src/cpp/README.md index 197e6dd..8541aa3 100644 --- a/flip_evaluator/cpp/README.md +++ b/src/cpp/README.md @@ -62,9 +62,9 @@ For business inquiries, please visit our website and submit the form: [NVIDIA Re CUDA support is enabled via the `FLIP_ENABLE_CUDA`, which can be passed to CMake on the command line with `-DFLIP_ENABLE_CUDA=ON` or set interactively with `ccmake` or `cmake-gui`. `FLIP_LIBRARY` option allows to output a library rather than an executable. - Usage: `flip[-cuda].exe --reference reference.{exr|png} --test test.{exr|png} [options]`, where the list of options can be seen by `flip[-cuda].exe -h`. -- Tested on Windows 10 version 22H2 and Windows 11 version 23H2 with CUDA 12.3. Compiled with Visual Studio 2022. If you use another version of CUDA, you will need to change the `CUDA 12.3` strings in the `CUDA.vcxproj` file accordingly. -- `flip_evaluator/tests/test.py` contains simple tests used to test whether code updates alter results. -- Weighted histograms are output as Python scripts. Running the script will create a PDF version of the histogram. Notice that those scripts require `numpy` and `matplotlib`, both of which may be installed using pip. These are automantically installed when installing the Python version of FLIP (see [README.md](https://github.com/NVlabs/flip/blob/main/flip_evaluator/python/README.md)). +- Tested on Windows 10 version 22H2 and Windows 11 version 23H2 with CUDA 12.6. Compiled with Visual Studio 2022. If you use another version of CUDA, you will need to change the `CUDA 12.6` strings in the `CUDA.vcxproj` file accordingly. +- `flip_evaluator/tests/test.py` contains simple tests used to test whether code updates alter results. Notice that those scripts require `numpy` and `matplotlib`, both of which may be installed using pip. +- Weighted histograms are output as Python scripts. Running the script will create a PDF version of the histogram. Like the test script, these scripts require `numpy` and `matplotlib`, both of which may be installed using pip. - The naming convention used for the FLIP tool's output is as follows (where `ppd` is the assumed number of pixels per degree, `tm` is the tone mapper assumed by HDR-FLIP, `cstart` and `cstop` are the shortest and longest exposures, respectively, assumed by HDR-FLIP, with `p` indicating a positive value and `m` indicating a negative value, diff --git a/flip_evaluator/cpp/tool/CMakeLists.txt b/src/cpp/tool/CMakeLists.txt similarity index 100% rename from flip_evaluator/cpp/tool/CMakeLists.txt rename to src/cpp/tool/CMakeLists.txt diff --git a/flip_evaluator/cpp/tool/CPP.vcxproj b/src/cpp/tool/CPP.vcxproj similarity index 100% rename from flip_evaluator/cpp/tool/CPP.vcxproj rename to src/cpp/tool/CPP.vcxproj diff --git a/flip_evaluator/cpp/tool/CPP.vcxproj.filters b/src/cpp/tool/CPP.vcxproj.filters similarity index 100% rename from flip_evaluator/cpp/tool/CPP.vcxproj.filters rename to src/cpp/tool/CPP.vcxproj.filters diff --git a/flip_evaluator/cpp/tool/CUDA.vcxproj b/src/cpp/tool/CUDA.vcxproj similarity index 99% rename from flip_evaluator/cpp/tool/CUDA.vcxproj rename to src/cpp/tool/CUDA.vcxproj index 444caa8..f13caee 100644 --- a/flip_evaluator/cpp/tool/CUDA.vcxproj +++ b/src/cpp/tool/CUDA.vcxproj @@ -51,7 +51,7 @@ - + @@ -113,6 +113,6 @@ - + \ No newline at end of file diff --git a/flip_evaluator/cpp/tool/CUDA.vcxproj.filters b/src/cpp/tool/CUDA.vcxproj.filters similarity index 100% rename from flip_evaluator/cpp/tool/CUDA.vcxproj.filters rename to src/cpp/tool/CUDA.vcxproj.filters diff --git a/flip_evaluator/cpp/tool/FLIP-tool.cpp b/src/cpp/tool/FLIP-tool.cpp similarity index 100% rename from flip_evaluator/cpp/tool/FLIP-tool.cpp rename to src/cpp/tool/FLIP-tool.cpp diff --git a/flip_evaluator/cpp/tool/FLIP-tool.cu b/src/cpp/tool/FLIP-tool.cu similarity index 100% rename from flip_evaluator/cpp/tool/FLIP-tool.cu rename to src/cpp/tool/FLIP-tool.cu diff --git a/flip_evaluator/cpp/tool/FLIPToolHelpers.h b/src/cpp/tool/FLIPToolHelpers.h similarity index 99% rename from flip_evaluator/cpp/tool/FLIPToolHelpers.h rename to src/cpp/tool/FLIPToolHelpers.h index ed66717..7c2f39f 100644 --- a/flip_evaluator/cpp/tool/FLIPToolHelpers.h +++ b/src/cpp/tool/FLIPToolHelpers.h @@ -484,7 +484,7 @@ namespace FLIPTool { std::cout << "FLIP v" << MajorVersion << "." << MinorVersion << ".\n"; commandLine.print(); - exit(EXIT_FAILURE); + exit(EXIT_SUCCESS); } if (!commandLine.optionSet("reference")) { @@ -501,7 +501,7 @@ namespace FLIPTool std::cout << "Error: you need to set a test image filename.\n Typically done with '-t testimg.{png,exr}' or '--test testimg.{png,exr}'.\n Use -h or --help for help message. Exiting\n"; exit(EXIT_FAILURE); } - if (commandLine.optionSet("help") || (commandLine.optionSet("basename") && commandLine.getOptionValues("test").size() != 1) || commandLine.getError()) + if ((commandLine.optionSet("basename") && commandLine.getOptionValues("test").size() != 1) || commandLine.getError()) { if (commandLine.getError()) { diff --git a/flip_evaluator/cpp/tool/commandline.h b/src/cpp/tool/commandline.h similarity index 100% rename from flip_evaluator/cpp/tool/commandline.h rename to src/cpp/tool/commandline.h diff --git a/flip_evaluator/cpp/tool/filename.h b/src/cpp/tool/filename.h similarity index 100% rename from flip_evaluator/cpp/tool/filename.h rename to src/cpp/tool/filename.h diff --git a/flip_evaluator/cpp/tool/imagehelpers.h b/src/cpp/tool/imagehelpers.h similarity index 100% rename from flip_evaluator/cpp/tool/imagehelpers.h rename to src/cpp/tool/imagehelpers.h diff --git a/flip_evaluator/cpp/tool/pooling.h b/src/cpp/tool/pooling.h similarity index 100% rename from flip_evaluator/cpp/tool/pooling.h rename to src/cpp/tool/pooling.h diff --git a/flip_evaluator/cpp/tool/stb_image.h b/src/cpp/tool/stb_image.h similarity index 100% rename from flip_evaluator/cpp/tool/stb_image.h rename to src/cpp/tool/stb_image.h diff --git a/flip_evaluator/cpp/tool/stb_image_write.h b/src/cpp/tool/stb_image_write.h similarity index 100% rename from flip_evaluator/cpp/tool/stb_image_write.h rename to src/cpp/tool/stb_image_write.h diff --git a/flip_evaluator/cpp/tool/tinyexr.h b/src/cpp/tool/tinyexr.h similarity index 100% rename from flip_evaluator/cpp/tool/tinyexr.h rename to src/cpp/tool/tinyexr.h diff --git a/flip_evaluator/__init__.py b/src/flip_evaluator/__init__.py similarity index 100% rename from flip_evaluator/__init__.py rename to src/flip_evaluator/__init__.py diff --git a/flip_evaluator/flip_python_api.py b/src/flip_evaluator/flip_python_api.py similarity index 96% rename from flip_evaluator/flip_python_api.py rename to src/flip_evaluator/flip_python_api.py index 5667dc0..e340f20 100644 --- a/flip_evaluator/flip_python_api.py +++ b/src/flip_evaluator/flip_python_api.py @@ -30,7 +30,7 @@ # SPDX-License-Identifier: BSD-3-Clause ################################################################################# -import pbflip +from flip_evaluator import pbflip import sys, os def evaluate(reference, test, dynamicRangeString, inputsRGB=True, applyMagma=True, computeMeanError=True, parameters={}): @@ -96,8 +96,8 @@ def evaluate(reference, test, dynamicRangeString, inputsRGB=True, applyMagma=Tru sys.exit(1) test = pbflip.load(test) - # Evaluate FLIP. Return error map. - return pbflip.evaluate(reference, test, useHDR, inputsRGB, computeMeanError, applyMagma, parameters) + # Evaluate FLIP. Return error map, mean FLIP error, and dictionary containing the parameters used. + return pbflip.evaluate(reference, test, useHDR, inputsRGB, applyMagma, computeMeanError, parameters) def load(imgpath): """ diff --git a/flip_evaluator/pybindFLIP.cpp b/src/nanobindFLIP.cpp similarity index 63% rename from flip_evaluator/pybindFLIP.cpp rename to src/nanobindFLIP.cpp index a0c5ac9..d2f7d92 100644 --- a/flip_evaluator/pybindFLIP.cpp +++ b/src/nanobindFLIP.cpp @@ -48,17 +48,32 @@ // Code by Pontus Ebelin (formerly Andersson) and Tomas Akenine-Moller. -#include -#include -#include +#include +#include +#include #include "cpp/FLIP.h" #include "cpp/tool/FLIPToolHelpers.h" -namespace py = pybind11; +namespace nb = nanobind; + +using Array3D = nb::ndarray, nb::device::cpu>; + +Array3D createThreeChannelImage(float*& data, const size_t imageHeight, const size_t imageWidth, const size_t numChannels) +{ + // Create an ndarray from the raw data and an owner to make sure the data is deallocated when no longer used. + nb::capsule owner(data, [](void* p) noexcept { + delete[](float*) p; + }); + + // Allocate 3D array + Array3D image(data, { imageHeight, imageWidth, numChannels }, owner); + + return image; +} // Load the .exr, .png, .bmp, or .tga file with path fileName. -py::array_t load(std::string fileName) +Array3D load(std::string fileName) { FLIP::image image; bool imageOk = ImageHelpers::load(image, fileName); @@ -68,28 +83,31 @@ py::array_t load(std::string fileName) exit(EXIT_FAILURE); } - const int imageWidth = image.getWidth(); - const int imageHeight = image.getHeight(); + const size_t imageWidth = image.getWidth(); + const size_t imageHeight = image.getHeight(); + const size_t channels = 3; - py::array_t numpyImage = py::array_t({ imageHeight, imageWidth, 3 });; + // Allocate memory for the ndarray. + float* data = new float[imageWidth * imageHeight * channels * sizeof(float)]; - py::buffer_info numpyImage_buf = numpyImage.request(); - float* ptr_numpyImage = static_cast(numpyImage_buf.ptr); + // Copy the image data to the allocated memory. + memcpy(data, image.getHostData(), imageWidth * imageHeight * sizeof(float) * channels); - memcpy(ptr_numpyImage, image.getHostData(), size_t(image.getWidth()) * image.getHeight() * sizeof(float) * 3); + // Create an ndarray from the raw data and an owner to make sure the data is deallocated when no longer used. + Array3D numpyImage = createThreeChannelImage(data, imageHeight, imageWidth, channels); return numpyImage; } // Convert linear RGB image to sRGB. -void sRGBToLinearRGB(float* image, const int imageWidth, const int imageHeight) +void sRGBToLinearRGB(float* image, const size_t imageWidth, const size_t imageHeight) { #pragma omp parallel for for (int y = 0; y < imageHeight; y++) { for (int x = 0; x < imageWidth; x++) { - int idx = (y * imageWidth + x) * 3; + size_t idx = (y * imageWidth + x) * 3; image[idx] = FLIP::color3::sRGBToLinearRGB(image[idx]); image[idx + 1] = FLIP::color3::sRGBToLinearRGB(image[idx + 1]); image[idx + 2] = FLIP::color3::sRGBToLinearRGB(image[idx + 2]); @@ -98,41 +116,41 @@ void sRGBToLinearRGB(float* image, const int imageWidth, const int imageHeight) } // Set parameters for evaluate function based on input settings. -FLIP::Parameters setParameters(py::dict inputParameters) +FLIP::Parameters setParameters(nb::dict inputParameters) { FLIP::Parameters parameters; for (auto item : inputParameters) { - std::string key = py::cast(item.first); + std::string key = nb::cast(item.first); std::string errorMessage = "Unrecognized parameter dictionary key or invalid value type. Available ones are \"ppd\" (float), \"startExposure\" (float), \"stopExposure\" (float), \"numExposures\" (int), and \"tonemapper\" (string)."; if (key == "ppd") { - parameters.PPD = py::cast(item.second); + parameters.PPD = nb::cast(item.second); } else if (key == "vc") { - auto vc = py::cast(item.second); - float distanceToDisplay = py::cast(vc[0]); - float displayWidthPixels = py::cast(vc[1]); - float displayWidthMeters = py::cast(vc[2]); + auto vc = nb::cast(item.second); + float distanceToDisplay = nb::cast(vc[0]); + float displayWidthPixels = nb::cast(vc[1]); + float displayWidthMeters = nb::cast(vc[2]); parameters.PPD = FLIP::calculatePPD(distanceToDisplay, displayWidthPixels, displayWidthMeters); } else if (key == "startExposure") { - parameters.startExposure = py::cast(item.second); + parameters.startExposure = nb::cast(item.second); } else if (key == "stopExposure") { - parameters.stopExposure = py::cast(item.second); + parameters.stopExposure = nb::cast(item.second); } else if (key == "numExposures") { - parameters.numExposures = py::cast(item.second); + parameters.numExposures = nb::cast(item.second); } else if (key == "tonemapper") { - parameters.tonemapper = py::cast(item.second); + parameters.tonemapper = nb::cast(item.second); } else { @@ -144,7 +162,7 @@ FLIP::Parameters setParameters(py::dict inputParameters) } // Update parameter dictionary that is returned to the Python side. -void updateInputParameters(const FLIP::Parameters& parameters, py::dict& inputParameters) +void updateInputParameters(const FLIP::Parameters& parameters, nb::dict& inputParameters) { inputParameters["ppd"] = parameters.PPD; inputParameters["startExposure"] = parameters.startExposure; @@ -156,7 +174,7 @@ void updateInputParameters(const FLIP::Parameters& parameters, py::dict& inputPa /** A simplified function for evaluating (the image metric called) FLIP between a reference image and a test image. Corresponds to the fourth evaluate() option in FLIP.h. * * @param[in] referenceInput Reference input image. For LDR, the content should be in [0,1]. The image is expected to have 3 floats per pixel. -* @param[in] testInput Test input image. For LDR, the content should be in [0,1]. +* @param[in] testInput Test input image. For LDR, the content should be in [0,1]. The image is expected to have 3 floats per pixel. * @param[in] useHDR Set to true if the input images are to be considered containing HDR content, i.e., not necessarily in [0,1]. * @param[in] inputsRGB Set to true if the input images are given in the sRGB color space. * @param[in] applyMagma A boolean indicating whether the output should have the Magma map applied to it before the image is returned. @@ -164,86 +182,64 @@ void updateInputParameters(const FLIP::Parameters& parameters, py::dict& inputPa * @param[in,out] inputParameters Contains parameters (e.g., PPD, exposure settings, etc). If the exposures have not been set by the user, then those will be computed (and returned). * @return tuple containing FLIP error map (in Magma if applyMagma is true), the mean FLIP error (computed if computeMeanFLIPError is true, else -1), and dictionary of parameters. */ -std::tuple, float, py::dict> evaluate(const py::array_t referenceInput, const py::array_t testInput, const bool useHDR, const bool inputsRGB = true, const bool applyMagma = true, const bool computeMeanFLIPError = true, py::dict inputParameters = {}) -{ - py::buffer_info r_buf = referenceInput.request(), t_buf = testInput.request(); - +nb::tuple evaluate(const Array3D referenceInput, const Array3D testInput, const bool useHDR, const bool inputsRGB = true, const bool applyMagma = true, const bool computeMeanFLIPError = true, nb::dict inputParameters = {}) +{ + size_t r_ndim = referenceInput.ndim(); + size_t t_ndim = testInput.ndim(); + // Check number of dimensions and resolution. - if (r_buf.ndim != 3 || t_buf.ndim != 3) + if (r_ndim != 3 || t_ndim != 3) { std::stringstream message; - message << "Number of dimensions must be three. The reference image has " << r_buf.ndim << " dimensions, while the test image has "<< t_buf.ndim << " dimensions."; + message << "Number of dimensions must be three. The reference image has " << r_ndim << " dimensions, while the test image has "<< t_ndim << " dimensions."; throw std::runtime_error(message.str()); } - - if (r_buf.shape[0] != t_buf.shape[0] || r_buf.shape[1] != t_buf.shape[1]) + + if (referenceInput.shape(0) != testInput.shape(0) || referenceInput.shape(1) != testInput.shape(1)) { std::stringstream message; - message << "Reference and test image resolutions differ.\nReference image resolution: " << r_buf.shape[0] << "x" << r_buf.shape[1] << "\nTest image resolution: "<< t_buf.shape[0] << "x" << t_buf.shape[1]; + message << "Reference and test image resolutions differ.\nReference image resolution: " << referenceInput.shape(0) << "x" << referenceInput.shape(1) << "\nTest image resolution: "<< testInput.shape(0) << "x" << testInput.shape(0); throw std::runtime_error(message.str()); } - - // Arrays for reference and test. - float* ptr_r = static_cast(r_buf.ptr); - float* ptr_t = static_cast(t_buf.ptr); // Image size. - const int nRows = int(r_buf.shape[0]), nCols = int(r_buf.shape[1]); + const size_t imageHeight = referenceInput.shape(0), imageWidth = referenceInput.shape(1); + const size_t nChannelsOut = applyMagma ? 3 : 1; // FLIP - float* flip; + float* flip = nullptr; // Allocated in FLIP::evaluate(). - // Create NumPy output array. - py::array_t flipNumpy; - int nChannelsOut; - if (applyMagma) - { - nChannelsOut = 3; - flipNumpy = py::array_t({ nRows, nCols, nChannelsOut}); - } - else - { - nChannelsOut = 1; - flipNumpy = py::array_t({ nRows, nCols }); - } - py::buffer_info flipNumpy_buf = flipNumpy.request(); - float* ptr_flipNumpy = static_cast(flipNumpy_buf.ptr); + // Arrays for reference and test. + float* referenceImage = new float[imageHeight * imageWidth * 3 * sizeof(float)]; + float* testImage = new float[imageHeight * imageWidth * 3 * sizeof(float)]; + memcpy(referenceImage, referenceInput.data(), imageHeight * imageWidth * sizeof(float) * 3); + memcpy(testImage, testInput.data(), imageHeight * imageWidth * sizeof(float) * 3); // Transform to linear RGB if desired. if (inputsRGB) { - sRGBToLinearRGB(ptr_r, nCols, nRows); - sRGBToLinearRGB(ptr_t, nCols, nRows); + sRGBToLinearRGB(referenceImage, imageWidth, imageHeight); + sRGBToLinearRGB(testImage, imageWidth, imageHeight); } // Run FLIP. FLIP::Parameters parameters = setParameters(inputParameters); float meanError = -1; - FLIP::evaluate(ptr_r, ptr_t, nCols, nRows, useHDR, parameters, applyMagma, computeMeanFLIPError, meanError, &flip); - - // Move output array info to correct buffer. -#pragma omp parallel for - for (int i = 0; i < nRows; i++) - { - for (int j = 0; j < nCols; j++) - { - for (int c = 0; c < nChannelsOut; c++) - { - int idx = (i * nCols + j) * nChannelsOut + c; - ptr_flipNumpy[idx] = flip[idx]; - } - } - } - delete flip; + FLIP::evaluate(referenceImage, testImage, int(imageWidth), int(imageHeight), useHDR, parameters, applyMagma, computeMeanFLIPError, meanError, &flip); - py::dict returnParams = {}; + nb::dict returnParams = {}; updateInputParameters(parameters, returnParams); - return std::make_tuple(flipNumpy, meanError, returnParams); + Array3D flipNumpy = createThreeChannelImage(flip, imageHeight, imageWidth, nChannelsOut); + + delete [] referenceImage; + delete [] testImage; + + return nb::make_tuple(flipNumpy, meanError, returnParams); } // Create command line, based on the Python command line string, for the FLIP tool to parse. -commandline generateCommandLine(const py::list argvPy) +commandline generateCommandLine(const nb::list argvPy) { size_t argc = argvPy.size(); char** argv = new char* [argc]; @@ -251,7 +247,7 @@ commandline generateCommandLine(const py::list argvPy) int counter = 0; for (auto item : argvPy) { - const std::string it = py::reinterpret_steal(item); + const std::string it = nb::steal(item).c_str(); argv[counter] = strdup(it.c_str()); counter++; } @@ -268,16 +264,16 @@ commandline generateCommandLine(const py::list argvPy) } // Run the FLIP tool based on Python command line string. -int execute(const py::list argvPy) +int execute(const nb::list argvPy) { commandline commandLine = generateCommandLine(argvPy); FLIPTool::execute(commandLine); - return 0; + return EXIT_SUCCESS; } // Setup the pybind11 module. -PYBIND11_MODULE(pbflip, handle) +NB_MODULE(pbflip, handle) { handle.doc() = "Load images (load), evaluate FLIP (evaluate), or run the full FLIP tool (execute)."; handle.def("load", &load); diff --git a/flip_evaluator/python/README.md b/src/python/README.md similarity index 95% rename from flip_evaluator/python/README.md rename to src/python/README.md index 486c781..4907655 100644 --- a/flip_evaluator/python/README.md +++ b/src/python/README.md @@ -13,7 +13,7 @@ and [Peter Shirley](https://research.nvidia.com/person/peter-shirley). This [repository](https://github.com/NVlabs/flip) implements the [LDR-FLIP](https://research.nvidia.com/publication/2020-07_FLIP) -and [HDR-FLIP](https://research.nvidia.com/publication/2021-05_HDR-FLIP) image error metrics in Python, using the C++ implementation through [pybind11](https://github.com/pybind/pybind11). +and [HDR-FLIP](https://research.nvidia.com/publication/2021-05_HDR-FLIP) image error metrics in Python, using the C++ implementation through [nanobind](https://github.com/wjakob/nanobind). Similarly, it implements the FLIP tool, presented in [Ray Tracing Gems II](https://www.realtimerendering.com/raytracinggems/rtg2/index.html). # License @@ -39,8 +39,8 @@ For business inquiries, please visit our website and submit the form: [NVIDIA Re - Tested with pip 24.0, Python 3.11.8, pybind11 2.11.1, and C++20. - FLIP runs on Windows, Linux (tested on Ubuntu 24.04), and OS X ($\ge$ 10.15), though its output might differ slightly between the different operative systems. The references used for `flip_evaluator/tests/test.py` are made for Windows. While the mean tests (means compared up to six decimal points) pass for each mentioned operative system, not all error map pixels are identical. - The code that implements FLIP metrics and the FLIP tool is available in [flip_evaluator/cpp/FLIP.h](https://github.com/NVlabs/flip/blob/main/flip_evaluator/cpp/FLIP.h) and [flip_evaluator/cpp/tool](https://github.com/NVlabs/flip/blob/main/flip_evaluator/cpp/tool), respectively. The relevant functions are called by the Python API using [pybind11](https://github.com/pybind/pybind11) (see [flip_evaluator/main.cpp](https://github.com/NVlabs/flip/blob/main/flip_evaluator/main.cpp)). The Python API is provided in `flip_evaluator/main.py`. - `flip_evaluator/tests/test.py` contains simple tests used to test whether code updates alter results. -- Weighted histograms are output as Python scripts. Running the script will create a PDF version of the histogram. Notice that those scripts require `numpy` and `matplotlib`, both of which are automatically installed during setup. + `flip_evaluator/tests/test.py` contains simple tests used to test whether code updates alter results. Notice that those scripts require `numpy` and `matplotlib`, both of which can be installed using pip. +- Weighted histograms are output as Python scripts. Running the script will create a PDF version of the histogram. Like the test scripts, these scripts require `numpy` and `matplotlib`, both of which can be installed using pip. - The naming convention used for the FLIP tool's output is as follows (where `ppd` is the assumed number of pixels per degree, `tm` is the tone mapper assumed by HDR-FLIP, `cstart` and `cstop` are the shortest and longest exposures, respectively, assumed by HDR-FLIP, with `p` indicating a positive value and `m` indicating a negative value, diff --git a/flip_evaluator/python/api_example.py b/src/python/api_example.py similarity index 100% rename from flip_evaluator/python/api_example.py rename to src/python/api_example.py diff --git a/flip_evaluator/pytorch/README.md b/src/pytorch/README.md similarity index 100% rename from flip_evaluator/pytorch/README.md rename to src/pytorch/README.md diff --git a/flip_evaluator/pytorch/data.py b/src/pytorch/data.py similarity index 100% rename from flip_evaluator/pytorch/data.py rename to src/pytorch/data.py diff --git a/flip_evaluator/pytorch/flip_loss.py b/src/pytorch/flip_loss.py similarity index 100% rename from flip_evaluator/pytorch/flip_loss.py rename to src/pytorch/flip_loss.py diff --git a/flip_evaluator/pytorch/train.py b/src/pytorch/train.py similarity index 100% rename from flip_evaluator/pytorch/train.py rename to src/pytorch/train.py diff --git a/flip_evaluator/tests/correct_hdrflip_cpp.png b/src/tests/correct_hdrflip_cpp.png similarity index 100% rename from flip_evaluator/tests/correct_hdrflip_cpp.png rename to src/tests/correct_hdrflip_cpp.png diff --git a/flip_evaluator/tests/correct_hdrflip_cuda.png b/src/tests/correct_hdrflip_cuda.png similarity index 100% rename from flip_evaluator/tests/correct_hdrflip_cuda.png rename to src/tests/correct_hdrflip_cuda.png diff --git a/flip_evaluator/tests/correct_ldrflip_cpp.png b/src/tests/correct_ldrflip_cpp.png similarity index 100% rename from flip_evaluator/tests/correct_ldrflip_cpp.png rename to src/tests/correct_ldrflip_cpp.png diff --git a/flip_evaluator/tests/correct_ldrflip_cuda.png b/src/tests/correct_ldrflip_cuda.png similarity index 100% rename from flip_evaluator/tests/correct_ldrflip_cuda.png rename to src/tests/correct_ldrflip_cuda.png diff --git a/flip_evaluator/tests/test.py b/src/tests/test.py similarity index 89% rename from flip_evaluator/tests/test.py rename to src/tests/test.py index c38e5fa..4b9af4e 100644 --- a/flip_evaluator/tests/test.py +++ b/src/tests/test.py @@ -71,14 +71,14 @@ test_str = "CUDA" correct_ldr_image_filename = "correct_ldrflip_cuda.png" correct_hdr_image_filename = "correct_hdrflip_cuda.png" - ldr_cmd = "../cpp/x64/release/flip-cuda.exe --reference ../images/reference.png --test ../images/test.png" - hdr_cmd = "../cpp/x64/release/flip-cuda.exe --reference ../images/reference.exr --test ../images/test.exr --no-exposure-map" + ldr_cmd = "../cpp/x64/release/flip-cuda.exe --reference ../../images/reference.png --test ../../images/test.png" + hdr_cmd = "../cpp/x64/release/flip-cuda.exe --reference ../../images/reference.exr --test ../../images/test.exr --no-exposure-map" elif(sys.argv[1] == "--cpp" or sys.argv[1] == "cpp" or sys.argv[1] == "-cpp"): test_str = "CPP" correct_ldr_image_filename = "correct_ldrflip_cpp.png" correct_hdr_image_filename = "correct_hdrflip_cpp.png" - ldr_cmd = "../cpp/x64/release/flip.exe --reference ../images/reference.png --test ../images/test.png" - hdr_cmd = "../cpp/x64/release/flip.exe --reference ../images/reference.exr --test ../images/test.exr --no-exposure-map" + ldr_cmd = "../cpp/x64/release/flip.exe --reference ../../images/reference.png --test ../../images/test.png" + hdr_cmd = "../cpp/x64/release/flip.exe --reference ../../images/reference.exr --test ../../images/test.exr --no-exposure-map" elif(sys.argv[1] == "--python" or sys.argv[1] == "python" or sys.argv[1] == "-python"): test_str = "PYTHON" correct_ldr_image_filename = "correct_ldrflip_cpp.png" # Python and C++ should give the same results, @@ -103,7 +103,7 @@ expected_hdr_mean = 0.283478 if test_str == "CUDA" or test_str == "CPP": - # Run FLIP on the reference/test image pairs in the ../images directory. + # Run FLIP on the reference/test image pairs in the ../../images directory. ldr_process = subprocess.run(ldr_cmd, stdout=subprocess.PIPE, text=True) hdr_process = subprocess.run(hdr_cmd, stdout=subprocess.PIPE, text=True) @@ -113,11 +113,11 @@ hdr_result_strings = hdr_process.stdout.split('\n') subpos = hdr_result_strings[8].find(':') - hdr_mean = float(hdr_result_strings[8][subpos + 2 : len(hdr_result_strings[4])]) + hdr_mean = float(hdr_result_strings[8][subpos + 2 : len(hdr_result_strings[8])]) else: - # Run FLIP on the reference/test image pairs in the ../images directory. - ldr_new_result, ldr_mean, _ = flip.evaluate("../images/reference.png", "../images/test.png", "LDR") - hdr_new_result, hdr_mean, _ = flip.evaluate("../images/reference.exr", "../images/test.exr", "HDR") + # Run FLIP on the reference/test image pairs in the ../../images directory. + ldr_new_result, ldr_mean, _ = flip.evaluate("../../images/reference.png", "../../images/test.png", "LDR") + hdr_new_result, hdr_mean, _ = flip.evaluate("../../images/reference.exr", "../../images/test.exr", "HDR") # Round to match the FLIP tool's output rounding ldr_mean = round(ldr_mean, 6) diff --git a/flip_evaluator/tests/test_pytorch.py b/src/tests/test_pytorch.py similarity index 94% rename from flip_evaluator/tests/test_pytorch.py rename to src/tests/test_pytorch.py index 8558380..d874c6a 100644 --- a/flip_evaluator/tests/test_pytorch.py +++ b/src/tests/test_pytorch.py @@ -73,16 +73,16 @@ # HDR test # Run the image pairs in the images directory - hdr_reference = read_exr('../images/reference.exr') # EXR - hdr_test = read_exr('../images/test.exr') # EXR + hdr_reference = read_exr('../../images/reference.exr') # EXR + hdr_test = read_exr('../../images/test.exr') # EXR hdrflip_loss_fn = HDRFLIPLoss() hdrflip_loss = hdrflip_loss_fn(hdr_test, hdr_reference) test_results.append(round(hdrflip_loss.item(), 4) == 0.2835) # LDR test # Run the image pairs in the images directory - ldr_reference = load_image_tensor('../images/reference.png') # sRGB - ldr_test = load_image_tensor('../images/test.png') # sRGB + ldr_reference = load_image_tensor('../../images/reference.png') # sRGB + ldr_test = load_image_tensor('../../images/test.png') # sRGB ldrflip_loss_fn = LDRFLIPLoss() ldrflip_loss = ldrflip_loss_fn(ldr_test, ldr_reference) test_results.append(round(ldrflip_loss.item(), 4) == 0.1597) From 1f4f67fa997066f1998715ddf9e6b47168359bff Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Fri, 8 Nov 2024 12:44:12 +0100 Subject: [PATCH 14/32] Minor fix --- .github/workflows/flip-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/flip-deploy.yml b/.github/workflows/flip-deploy.yml index 6e7d5ed..b3ede20 100644 --- a/.github/workflows/flip-deploy.yml +++ b/.github/workflows/flip-deploy.yml @@ -1,6 +1,6 @@ # Source: https://github.com/pypa/cibuildwheel/blob/main/examples/github-deploy.yml. -name: Build and upload to PyPI +name: Build wheels on: workflow_dispatch: From 2d51b0ab63a479e9d4e32eb696fe541b64311be0 Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Fri, 8 Nov 2024 13:00:04 +0100 Subject: [PATCH 15/32] More workflow fixes --- .github/workflows/flip-deploy.yml | 65 +++++++++++++++++++++++++++---- .github/workflows/flip_ci.yml | 6 +-- README.md | 2 +- 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/.github/workflows/flip-deploy.yml b/.github/workflows/flip-deploy.yml index b3ede20..39204e5 100644 --- a/.github/workflows/flip-deploy.yml +++ b/.github/workflows/flip-deploy.yml @@ -1,4 +1,4 @@ -# Source: https://github.com/pypa/cibuildwheel/blob/main/examples/github-deploy.yml. +# Much of the code retrieved from Mitsuba3 (https://github.com/mitsuba-renderer/mitsuba3/blob/master/.github/workflows/wheels.yml.) name: Build wheels @@ -14,23 +14,72 @@ on: jobs: build_wheels: - name: Build wheels on ${{ matrix.os }} - runs-on: ${{ matrix.os }} strategy: matrix: # macos-13 is an intel runner, macos-14 is apple silicon os: [ubuntu-latest, windows-latest, macos-13, macos-14] - python: [cp38, cp39, cp310, cp311, cp312, cp313] + python: [cp38, cp39, cp310, cp311, cp312, cp312_stable, cp313] + exclude: + # The first Python version to target Apple arm64 architectures is 3.9. + - os: macos-14 + python: cp38 + name: > + ${{ matrix.python }} wheel for ${{ matrix.os }} + ${{ (endsWith(matrix.python, '_stable') && '(stable ABI)') || '' }} + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - - name: Build wheels - uses: pypa/cibuildwheel@v2.21.3 + - uses: actions/setup-python@v4 + name: Install Python + with: + python-version: '3.10' + + - name: Install cibuildwheel + run: | + python -m pip install cibuildwheel==2.20.0 - - uses: actions/upload-artifact@v4 + ################################################################ + # Set up envvars to build the correct wheel (stable ABI or not) + ################################################################ + + - name: Prepare cibuildwheel environment (UNIX) + if: ${{ ! endsWith(matrix.python, '_stable') && runner.os != 'Windows' }} + run: | + echo "CIBW_BUILD=${{ matrix.python }}-*" >> $GITHUB_ENV && + echo "CIBW_CONFIG_SETTINGS=\"cmake.args=-DMI_DEFAULT_VARIANTS=\"scalar_rgb,scalar_spectral,scalar_spectral_polarized,llvm_ad_rgb,llvm_ad_mono,llvm_ad_mono_polarized,llvm_ad_spectral,llvm_ad_spectral_polarized,cuda_ad_rgb,cuda_ad_mono,cuda_ad_mono_polarized,cuda_ad_spectral,cuda_ad_spectral_polarized\"\"" >> $GITHUB_ENV + + - name: Prepare cibuildwheel environment (Windows) + if: ${{ ! endsWith(matrix.python, '_stable') && runner.os == 'Windows' }} + run: | + echo "CIBW_BUILD=${{ matrix.python }}-*" >> $env:GITHUB_ENV + echo "CIBW_CONFIG_SETTINGS=cmake.args='-DMI_DEFAULT_VARIANTS='scalar_rgb,scalar_spectral,scalar_spectral_polarized,llvm_ad_rgb,llvm_ad_mono,llvm_ad_mono_polarized,llvm_ad_spectral,llvm_ad_spectral_polarized,cuda_ad_rgb,cuda_ad_mono,cuda_ad_mono_polarized,cuda_ad_spectral,cuda_ad_spectral_polarized''" >> $env:GITHUB_ENV + + - name: Prepare cibuildwheel environment for stable ABI wheel (UNIX) + if: ${{ endsWith(matrix.python, '_stable') && runner.os != 'Windows' }} + run: | + stable_cp=$(echo ${{ matrix.python }} | cut -d_ -f1) && + echo "CIBW_BUILD=${stable_cp}-*" >> $GITHUB_ENV && + echo "CIBW_CONFIG_SETTINGS=\"wheel.py-api=cp312\" \"cmake.args=-DDRJIT_STABLE_ABI=ON -DMI_STABLE_ABI=ON -DMI_DEFAULT_VARIANTS=\"scalar_rgb,scalar_spectral,scalar_spectral_polarized,llvm_ad_rgb,llvm_ad_mono,llvm_ad_mono_polarized,llvm_ad_spectral,llvm_ad_spectral_polarized,cuda_ad_rgb,cuda_ad_mono,cuda_ad_mono_polarized,cuda_ad_spectral,cuda_ad_spectral_polarized\"\"" >> $GITHUB_ENV + + - name: Prepare cibuildwheel environment for stable ABI wheel (Windows) + if: ${{ endsWith(matrix.python, '_stable') && runner.os == 'Windows' }} + run: | + $stable_cp = '${{ matrix.python }}' -split '_' + echo "CIBW_BUILD=$($stable_cp[0])-*" >> $env:GITHUB_ENV + echo "CIBW_CONFIG_SETTINGS=wheel.py-api=cp312 cmake.args='-DDRJIT_STABLE_ABI=ON -DMI_STABLE_ABI=ON -DMI_DEFAULT_VARIANTS='scalar_rgb,scalar_spectral,scalar_spectral_polarized,llvm_ad_rgb,llvm_ad_mono,llvm_ad_mono_polarized,llvm_ad_spectral,llvm_ad_spectral_polarized,cuda_ad_rgb,cuda_ad_mono,cuda_ad_mono_polarized,cuda_ad_spectral,cuda_ad_spectral_polarized''" >> $env:GITHUB_ENV + + ######################### + # Build and store wheels + ######################### + - name: Build wheel + run: | + python -m cibuildwheel --output-dir wheelhouse + + - uses: actions/upload-artifact@v3 with: - name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} + name: wheels path: ./wheelhouse/*.whl build_sdist: diff --git a/.github/workflows/flip_ci.yml b/.github/workflows/flip_ci.yml index 90e365a..06f3d43 100644 --- a/.github/workflows/flip_ci.yml +++ b/.github/workflows/flip_ci.yml @@ -24,12 +24,12 @@ jobs: - name: Configure CMake run: > - cmake -LA -B ${{github.workspace}}/flip_evaluator/build -S ${{github.workspace}}/flip_evaluator/ + cmake -LA -B ${{github.workspace}}/src/build -S ${{github.workspace}}/src/ -DCMAKE_BUILD_TYPE=${{ matrix.config }} - -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/flip_evaluator/build/install + -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/src/build/install -DCMAKE_CUDA_ARCHITECTURES=all -DCMAKE_CUDA_HOST_COMPILER=g++-10 -DFLIP_ENABLE_CUDA=${{ matrix.os == 'ubuntu-latest' }} - name: Build - run: cmake --build ${{github.workspace}}/flip_evaluator/build --config ${{ matrix.config }} --target install + run: cmake --build ${{github.workspace}}/src/build --config ${{ matrix.config }} --target install diff --git a/README.md b/README.md index f5e2b47..abdd09f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![Teaser image](flip_evaluator/images/teaser.png "Teaser image") +![Teaser image](images/teaser.png "Teaser image") # FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.5) From eaeefbd91fbbdcc65602978f43debc1f086f68da Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Fri, 8 Nov 2024 13:07:59 +0100 Subject: [PATCH 16/32] Check APPLE before UNIX --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ea1985e..bbe115b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,7 +65,7 @@ endif() if(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -openmp") -elseif(UNIX) +elseif((NOT APPLE) AND UNIX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgomp") endif() From 5d8e66363ae950508902226489cbe9e0ad2621e6 Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Fri, 8 Nov 2024 14:10:54 +0100 Subject: [PATCH 17/32] Test only Windows --- .github/workflows/flip-deploy.yml | 35 +++---------------------------- README.md | 4 ++-- pyproject.toml | 2 +- 3 files changed, 6 insertions(+), 35 deletions(-) diff --git a/.github/workflows/flip-deploy.yml b/.github/workflows/flip-deploy.yml index 39204e5..56e8523 100644 --- a/.github/workflows/flip-deploy.yml +++ b/.github/workflows/flip-deploy.yml @@ -17,7 +17,8 @@ jobs: strategy: matrix: # macos-13 is an intel runner, macos-14 is apple silicon - os: [ubuntu-latest, windows-latest, macos-13, macos-14] + #os: [ubuntu-latest, windows-latest, macos-13, macos-14] + os: [windows-latest] python: [cp38, cp39, cp310, cp311, cp312, cp312_stable, cp313] exclude: # The first Python version to target Apple arm64 architectures is 3.9. @@ -34,42 +35,12 @@ jobs: - uses: actions/setup-python@v4 name: Install Python with: - python-version: '3.10' + python-version: '3.8' - name: Install cibuildwheel run: | python -m pip install cibuildwheel==2.20.0 - ################################################################ - # Set up envvars to build the correct wheel (stable ABI or not) - ################################################################ - - - name: Prepare cibuildwheel environment (UNIX) - if: ${{ ! endsWith(matrix.python, '_stable') && runner.os != 'Windows' }} - run: | - echo "CIBW_BUILD=${{ matrix.python }}-*" >> $GITHUB_ENV && - echo "CIBW_CONFIG_SETTINGS=\"cmake.args=-DMI_DEFAULT_VARIANTS=\"scalar_rgb,scalar_spectral,scalar_spectral_polarized,llvm_ad_rgb,llvm_ad_mono,llvm_ad_mono_polarized,llvm_ad_spectral,llvm_ad_spectral_polarized,cuda_ad_rgb,cuda_ad_mono,cuda_ad_mono_polarized,cuda_ad_spectral,cuda_ad_spectral_polarized\"\"" >> $GITHUB_ENV - - - name: Prepare cibuildwheel environment (Windows) - if: ${{ ! endsWith(matrix.python, '_stable') && runner.os == 'Windows' }} - run: | - echo "CIBW_BUILD=${{ matrix.python }}-*" >> $env:GITHUB_ENV - echo "CIBW_CONFIG_SETTINGS=cmake.args='-DMI_DEFAULT_VARIANTS='scalar_rgb,scalar_spectral,scalar_spectral_polarized,llvm_ad_rgb,llvm_ad_mono,llvm_ad_mono_polarized,llvm_ad_spectral,llvm_ad_spectral_polarized,cuda_ad_rgb,cuda_ad_mono,cuda_ad_mono_polarized,cuda_ad_spectral,cuda_ad_spectral_polarized''" >> $env:GITHUB_ENV - - - name: Prepare cibuildwheel environment for stable ABI wheel (UNIX) - if: ${{ endsWith(matrix.python, '_stable') && runner.os != 'Windows' }} - run: | - stable_cp=$(echo ${{ matrix.python }} | cut -d_ -f1) && - echo "CIBW_BUILD=${stable_cp}-*" >> $GITHUB_ENV && - echo "CIBW_CONFIG_SETTINGS=\"wheel.py-api=cp312\" \"cmake.args=-DDRJIT_STABLE_ABI=ON -DMI_STABLE_ABI=ON -DMI_DEFAULT_VARIANTS=\"scalar_rgb,scalar_spectral,scalar_spectral_polarized,llvm_ad_rgb,llvm_ad_mono,llvm_ad_mono_polarized,llvm_ad_spectral,llvm_ad_spectral_polarized,cuda_ad_rgb,cuda_ad_mono,cuda_ad_mono_polarized,cuda_ad_spectral,cuda_ad_spectral_polarized\"\"" >> $GITHUB_ENV - - - name: Prepare cibuildwheel environment for stable ABI wheel (Windows) - if: ${{ endsWith(matrix.python, '_stable') && runner.os == 'Windows' }} - run: | - $stable_cp = '${{ matrix.python }}' -split '_' - echo "CIBW_BUILD=$($stable_cp[0])-*" >> $env:GITHUB_ENV - echo "CIBW_CONFIG_SETTINGS=wheel.py-api=cp312 cmake.args='-DDRJIT_STABLE_ABI=ON -DMI_STABLE_ABI=ON -DMI_DEFAULT_VARIANTS='scalar_rgb,scalar_spectral,scalar_spectral_polarized,llvm_ad_rgb,llvm_ad_mono,llvm_ad_mono_polarized,llvm_ad_spectral,llvm_ad_spectral_polarized,cuda_ad_rgb,cuda_ad_mono,cuda_ad_mono_polarized,cuda_ad_spectral,cuda_ad_spectral_polarized''" >> $env:GITHUB_ENV - ######################### # Build and store wheels ######################### diff --git a/README.md b/README.md index abdd09f..52e9110 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ This work is made available under a [BSD 3-Clause License](LICENSE). The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#bsd-3-clause-license),
and `stb_image`, which is subject to an [MIT License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#mit-license). -For individual contributions to the project, please confer the [Individual Contributor License Agreement](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/CLA.md). +For individual contributions to the project, please confer the [Individual Contributor License Agreement](https://github.com/NVlabs/flip/blob/main/misc/CLA.md). For business inquiries, please visit our website and submit the form: [NVIDIA Research Licensing](https://www.nvidia.com/en-us/research/inquiries/). @@ -63,7 +63,7 @@ pip install flip-evaluator **Usage:**
API:
-See the example script `flip_evaluator/python/api_example.py`. +See the example script `src/python/api_example.py`. Tool: ``` diff --git a/pyproject.toml b/pyproject.toml index 5bef361..ee529b0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,7 +65,7 @@ MACOSX_DEPLOYMENT_TARGET = "10.15" [tool.scikit-build] minimum-version = "0.4" sdist.include = ["src/flip_evaluator/__init__.py", "src/flip_evaluator/flip_python_api.py", "src/cpp/FLIP.h", "src/cpp/tool/*.h"] -sdist.exclude = [".github", ".gitignore", "images", "misc", "dist", "*__pycache__*", "src/pytorch", "src/cmake", "src/tests", "src/CMakeLists.txt", "src/flip_evaluator/api_example.py", "src/flip_evaluator/README.md", "src/cpp/FLIP.sln", "src/cpp/CMakeLists.txt", "src/cpp/README.md", "src/cpp/tool/CMakeLists.txt", "src/cpp/tool/CPP.vcxproj*", "src/cpp/tool/CUDA.vcxproj*", "src/cpp/tool/*.cpp", "src/cpp/tool/*.cu"] +sdist.exclude = [".github", ".gitignore", "images", "misc", "dist", "*__pycache__*", "src/pytorch", "src/cmake", "src/tests", "src/CMakeLists.txt", "src/python", "src/cpp/FLIP.sln", "src/cpp/CMakeLists.txt", "src/cpp/README.md", "src/cpp/tool/CMakeLists.txt", "src/cpp/tool/CPP.vcxproj*", "src/cpp/tool/CUDA.vcxproj*", "src/cpp/tool/*.cpp", "src/cpp/tool/*.cu"] [tool.hatch.metadata.hooks.fancy-pypi-readme] content-type = "text/markdown" From 07755871990e46464a78d02808411d8e54b09b1a Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Mon, 11 Nov 2024 08:24:21 +0100 Subject: [PATCH 18/32] Fixed case issue. Now builds on Linux --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bbe115b..6f4e8d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,6 @@ execute_process( OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE nanobind_ROOT) find_package(nanobind CONFIG REQUIRED) -nanobind_add_module(pbflip STABLE_ABI src/nanobindflip.cpp) +nanobind_add_module(pbflip STABLE_ABI src/nanobindFLIP.cpp) install(TARGETS pbflip LIBRARY DESTINATION flip_evaluator) From 3b654bb2b83f80e46c54f90a2e625dc01652628b Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Mon, 11 Nov 2024 09:02:21 +0100 Subject: [PATCH 19/32] Fixed some broken links and re-added Unix/macOS wheels --- .github/workflows/flip-deploy.yml | 3 +-- README.md | 30 +++++++++++++++--------------- src/cpp/README.md | 10 +++++----- src/python/README.md | 22 +++++++++++----------- src/pytorch/README.md | 6 +++--- 5 files changed, 35 insertions(+), 36 deletions(-) diff --git a/.github/workflows/flip-deploy.yml b/.github/workflows/flip-deploy.yml index 56e8523..4e1fe7f 100644 --- a/.github/workflows/flip-deploy.yml +++ b/.github/workflows/flip-deploy.yml @@ -17,8 +17,7 @@ jobs: strategy: matrix: # macos-13 is an intel runner, macos-14 is apple silicon - #os: [ubuntu-latest, windows-latest, macos-13, macos-14] - os: [windows-latest] + os: [ubuntu-latest, windows-latest, macos-13, macos-14] python: [cp38, cp39, cp310, cp311, cp312, cp312_stable, cp313] exclude: # The first Python version to target Apple arm64 architectures is 3.9. diff --git a/README.md b/README.md index 52e9110..f5eb25c 100644 --- a/README.md +++ b/README.md @@ -18,18 +18,18 @@ This repository holds implementations of the [LDR-FLIP](https://research.nvidia. and [HDR-FLIP](https://research.nvidia.com/publication/2021-05_HDR-FLIP) image error metrics. It also holds code for the FLIP tool, presented in [Ray Tracing Gems II](https://www.realtimerendering.com/raytracinggems/rtg2/index.html). -The changes made for the different versions of FLIP are summarized in the [version list](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/versionList.md). +The changes made for the different versions of FLIP are summarized in the [version list](https://github.com/NVlabs/flip/blob/main/misc/versionList.md). -[A list of papers](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/papersUsingFLIP.md) that use/cite FLIP. +[A list of papers](https://github.com/NVlabs/flip/blob/main/misc/papersUsingFLIP.md) that use/cite FLIP. -[A note](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/precision.md) about the precision of FLIP. +[A note](https://github.com/NVlabs/flip/blob/main/misc/precision.md) about the precision of FLIP. [An image gallery](https://research.nvidia.com/node/3525) displaying a large quantity of reference/test images and corresponding error maps from different metrics. **Note**: since v1.5, the Python version of FLIP can now be installed via `pip install flip-evaluator`. -**Note**: in v1.3, we switched to a *single header* ([FLIP.h](flip_evaluator/cpp/FLIP.h)) for C++/CUDA for easier integration. +**Note**: in v1.3, we switched to a *single header* ([FLIP.h](src/cpp/FLIP.h)) for C++/CUDA for easier integration. # License @@ -37,8 +37,8 @@ Copyright © 2020-2024, NVIDIA Corporation & Affiliates. All rights reserved. This work is made available under a [BSD 3-Clause License](LICENSE). -The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#bsd-3-clause-license),
-and `stb_image`, which is subject to an [MIT License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#mit-license). +The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/misc/LICENSE-third-party.md#bsd-3-clause-license),
+and `stb_image`, which is subject to an [MIT License](https://github.com/NVlabs/flip/blob/main/misc/LICENSE-third-party.md#mit-license). For individual contributions to the project, please confer the [Individual Contributor License Agreement](https://github.com/NVlabs/flip/blob/main/misc/CLA.md). @@ -70,12 +70,12 @@ Tool: flip --reference reference.{exr|png} --test test.{exr|png} [--options] ``` -See the [README](https://github.com/NVlabs/flip/blob/main/flip_evaluator/python/README.md) in the `python` folder and run `flip -h` for further information and usage instructions. +See the [README](https://github.com/NVlabs/flip/blob/main/src/python/README.md) in the `python` folder and run `flip -h` for further information and usage instructions. # C++ and CUDA (API and Tool) **Setup:** -The `flip_evaluator/cpp/FLIP.sln` solution contains one CUDA backend project and one pure C++ backend project. +The `src/cpp/FLIP.sln` solution contains one CUDA backend project and one pure C++ backend project. Compiling the CUDA project requires a CUDA compatible GPU. Instruction on how to install CUDA can be found [here](https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/index.html). @@ -95,14 +95,14 @@ CUDA support is enabled via the `FLIP_ENABLE_CUDA`, which can be passed to CMake **Usage:**
API:
-See the [README](https://github.com/NVlabs/flip/blob/main/flip_evaluator/cpp/README.md). +See the [README](https://github.com/NVlabs/flip/blob/main/src/cpp/README.md). Tool: ``` flip[-cuda].exe --reference reference.{exr|png} --test test.{exr|png} [options] ``` -See the [README](https://github.com/NVlabs/flip/blob/main/flip_evaluator/cpp/README.md) in the `flip_evaluator/cpp` folder and run `flip[-cuda].exe -h` for further information and usage instructions. +See the [README](https://github.com/NVlabs/flip/blob/main/src/cpp/README.md) in the `src/cpp` folder and run `flip[-cuda].exe -h` for further information and usage instructions. # PyTorch (Loss Function) **Setup** (with Anaconda3 or Miniconda): @@ -117,21 +117,21 @@ conda install -c conda-forge openexr-python *Remember to activate the* `flip_dl` *environment through* `conda activate flip_dl` *before using the loss function.* -LDR- and HDR-FLIP are implemented as loss modules in `flip_evaluator/pytorch/flip_loss.py`. An example where the loss function is used to train a simple autoencoder is provided in `flip_evaluator/pytorch/train.py`. +LDR- and HDR-FLIP are implemented as loss modules in `src/pytorch/flip_loss.py`. An example where the loss function is used to train a simple autoencoder is provided in `src/pytorch/train.py`. -See the [README](https://github.com/NVlabs/flip/blob/main/flip_evaluator/pytorch/README.md) in the `pytorch` folder for further information and usage instructions. +See the [README](https://github.com/NVlabs/flip/blob/main/src/pytorch/README.md) in the `pytorch` folder for further information and usage instructions. # Citation If your work uses the FLIP tool to find the errors between *low dynamic range* images, please cite the LDR-FLIP paper:
-[Paper](https://research.nvidia.com/publication/2020-07_FLIP) | [BibTeX](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LDRFLIP.txt) +[Paper](https://research.nvidia.com/publication/2020-07_FLIP) | [BibTeX](https://github.com/NVlabs/flip/blob/main/misc/LDRFLIP.txt) If it uses the FLIP tool to find the errors between *high dynamic range* images, instead cite the HDR-FLIP paper:
-[Paper](https://research.nvidia.com/publication/2021-05_HDR-FLIP) | [BibTeX](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/HDRFLIP.txt) +[Paper](https://research.nvidia.com/publication/2021-05_HDR-FLIP) | [BibTeX](https://github.com/NVlabs/flip/blob/main/misc/HDRFLIP.txt) Should your work use the FLIP tool in a more general fashion, please cite the Ray Tracing Gems II article:
-[Chapter](https://link.springer.com/chapter/10.1007%2F978-1-4842-7185-8_19) | [BibTeX](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/FLIP.txt) +[Chapter](https://link.springer.com/chapter/10.1007%2F978-1-4842-7185-8_19) | [BibTeX](https://github.com/NVlabs/flip/blob/main/misc/FLIP.txt) # Acknowledgements We appreciate the following peoples' contributions to this repository: diff --git a/src/cpp/README.md b/src/cpp/README.md index 8541aa3..7429f75 100644 --- a/src/cpp/README.md +++ b/src/cpp/README.md @@ -30,10 +30,10 @@ Copyright © 2020-2024, NVIDIA Corporation & Affiliates. All rights reserved. This work is made available under a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/LICENSE). -The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#bsd-3-clause-license),
-and `stb_image`, which is subject to an [MIT License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#mit-license). +The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/misc/LICENSE-third-party.md#bsd-3-clause-license),
+and `stb_image`, which is subject to an [MIT License](https://github.com/NVlabs/flip/blob/main/misc/LICENSE-third-party.md#mit-license). -For individual contributions to the project, please confer the [Individual Contributor License Agreement](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/CLA.md). +For individual contributions to the project, please confer the [Individual Contributor License Agreement](https://github.com/NVlabs/flip/blob/main/misc/CLA.md). For business inquiries, please visit our website and submit the form: [NVIDIA Research Licensing](https://www.nvidia.com/en-us/research/inquiries/). @@ -63,7 +63,7 @@ For business inquiries, please visit our website and submit the form: [NVIDIA Re `FLIP_LIBRARY` option allows to output a library rather than an executable. - Usage: `flip[-cuda].exe --reference reference.{exr|png} --test test.{exr|png} [options]`, where the list of options can be seen by `flip[-cuda].exe -h`. - Tested on Windows 10 version 22H2 and Windows 11 version 23H2 with CUDA 12.6. Compiled with Visual Studio 2022. If you use another version of CUDA, you will need to change the `CUDA 12.6` strings in the `CUDA.vcxproj` file accordingly. -- `flip_evaluator/tests/test.py` contains simple tests used to test whether code updates alter results. Notice that those scripts require `numpy` and `matplotlib`, both of which may be installed using pip. +- `src/tests/test.py` contains simple tests used to test whether code updates alter results. Notice that those scripts require `numpy` and `matplotlib`, both of which may be installed using pip. - Weighted histograms are output as Python scripts. Running the script will create a PDF version of the histogram. Like the test script, these scripts require `numpy` and `matplotlib`, both of which may be installed using pip. - The naming convention used for the FLIP tool's output is as follows (where `ppd` is the assumed number of pixels per degree, `tm` is the tone mapper assumed by HDR-FLIP, `cstart` and `cstop` are the shortest and longest exposures, respectively, assumed by HDR-FLIP, @@ -110,7 +110,7 @@ For business inquiries, please visit our website and submit the form: [NVIDIA Re Text file: `.txt`
**Example usage:** -After compiling the `flip_evaluator/cpp/FLIP.sln` project, navigate to the `flip[-cuda].exe` executable and try: +After compiling the `src/cpp/FLIP.sln` project, navigate to the `flip[-cuda].exe` executable and try: ``` flip[-cuda].exe -r ../../../images/reference.exr -t ../../../images/test.exr ``` diff --git a/src/python/README.md b/src/python/README.md index 4907655..6a1df10 100644 --- a/src/python/README.md +++ b/src/python/README.md @@ -22,10 +22,10 @@ Copyright © 2020-2024, NVIDIA Corporation & Affiliates. All rights reserved. This work is made available under a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/LICENSE). -The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#bsd-3-clause-license),
-and `stb_image`, which is subject to an [MIT License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#mit-license). +The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/misc/LICENSE-third-party.md#bsd-3-clause-license),
+and `stb_image`, which is subject to an [MIT License](https://github.com/NVlabs/flip/blob/main/misc/LICENSE-third-party.md#mit-license). -For individual contributions to the project, please confer the [Individual Contributor License Agreement](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/CLA.md). +For individual contributions to the project, please confer the [Individual Contributor License Agreement](https://github.com/NVlabs/flip/blob/main/misc/CLA.md). For business inquiries, please visit our website and submit the form: [NVIDIA Research Licensing](https://www.nvidia.com/en-us/research/inquiries/). @@ -34,12 +34,12 @@ For business inquiries, please visit our website and submit the form: [NVIDIA Re ``` pip install flip-evaluator ``` -- Usage (API): See example in the script `flip_evaluator/python/api_example.py`. +- Usage (API): See example in the script `src/python/api_example.py`. - Usage (tool): `flip --reference reference.{exr|png} --test test.{exr|png} [--options]`, where the list of options can be seen by `flip -h`. - Tested with pip 24.0, Python 3.11.8, pybind11 2.11.1, and C++20. -- FLIP runs on Windows, Linux (tested on Ubuntu 24.04), and OS X ($\ge$ 10.15), though its output might differ slightly between the different operative systems. The references used for `flip_evaluator/tests/test.py` are made for Windows. While the mean tests (means compared up to six decimal points) pass for each mentioned operative system, not all error map pixels are identical. -- The code that implements FLIP metrics and the FLIP tool is available in [flip_evaluator/cpp/FLIP.h](https://github.com/NVlabs/flip/blob/main/flip_evaluator/cpp/FLIP.h) and [flip_evaluator/cpp/tool](https://github.com/NVlabs/flip/blob/main/flip_evaluator/cpp/tool), respectively. The relevant functions are called by the Python API using [pybind11](https://github.com/pybind/pybind11) (see [flip_evaluator/main.cpp](https://github.com/NVlabs/flip/blob/main/flip_evaluator/main.cpp)). The Python API is provided in `flip_evaluator/main.py`. - `flip_evaluator/tests/test.py` contains simple tests used to test whether code updates alter results. Notice that those scripts require `numpy` and `matplotlib`, both of which can be installed using pip. +- FLIP runs on Windows, Linux (tested on Ubuntu 24.04), and OS X ($\ge$ 10.15), though its output might differ slightly between the different operative systems. The references used for `src/tests/test.py` are made for Windows. While the mean tests (means compared up to six decimal points) pass for each mentioned operative system, not all error map pixels are identical. +- The code that implements FLIP metrics and the FLIP tool is available in [src/cpp/FLIP.h](https://github.com/NVlabs/flip/blob/main/cpp/FLIP.h) and [src/cpp/tool](https://github.com/NVlabs/flip/blob/main/cpp/tool), respectively. The relevant functions are called by the Python API using [nanobind](https://github.com/wjakob/nanobind) (see [src/nanobindFLIP.cpp](https://github.com/NVlabs/flip/blob/main/src/nanobindFLIP.cpp)). The Python API is provided in `src/flip_evaluator/flip_python_api.py`. + `src/tests/test.py` contains simple tests used to test whether code updates alter results. Notice that those scripts require `numpy` and `matplotlib`, both of which can be installed using pip. - Weighted histograms are output as Python scripts. Running the script will create a PDF version of the histogram. Like the test scripts, these scripts require `numpy` and `matplotlib`, both of which can be installed using pip. - The naming convention used for the FLIP tool's output is as follows (where `ppd` is the assumed number of pixels per degree, `tm` is the tone mapper assumed by HDR-FLIP, `cstart` and `cstop` are the shortest and longest exposures, respectively, assumed by HDR-FLIP, @@ -86,12 +86,12 @@ For business inquiries, please visit our website and submit the form: [NVIDIA Re Text file: `.txt`
**Example usage:** -To test the API, please inspect the `flip_evaluator/python/api_example.py` script. This shows how the available API commands may be used. -Please note that not all capabilities of the tool is available through the Python API. For example, the exposure map is not output when running HDR-FLIP. For that, use the tool or the C++ API in [FLIP.h](https://github.com/NVlabs/flip/blob/main/flip_evaluator/cpp/FLIP.h). +To test the API, please inspect the `src/python/api_example.py` script. This shows how the available API commands may be used. +Please note that not all capabilities of the tool is available through the Python API. For example, the exposure map is not output when running HDR-FLIP. For that, use the tool or the C++ API in [FLIP.h](https://github.com/NVlabs/flip/blob/main/src/cpp/FLIP.h). -To test the tool, start a shell, navigate to `flip_evaluator/python` and try: +To test the tool, start a shell, navigate to `images/` and try: ``` - flip -r ../images/reference.exr -t ../images/test.exr + flip -r reference.exr -t test.exr ``` The result should be: ``` diff --git a/src/pytorch/README.md b/src/pytorch/README.md index 8cf8765..14c2f01 100644 --- a/src/pytorch/README.md +++ b/src/pytorch/README.md @@ -21,10 +21,10 @@ Copyright © 2020-2024, NVIDIA Corporation & Affiliates. All rights reserved. This work is made available under a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/LICENSE). -The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#bsd-3-clause-license),
-and `stb_image`, which is subject to an [MIT License](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/LICENSE-third-party.md#mit-license). +The repository distributes code for `tinyexr`, which is subject to a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/misc/LICENSE-third-party.md#bsd-3-clause-license),
+and `stb_image`, which is subject to an [MIT License](https://github.com/NVlabs/flip/blob/main/misc/LICENSE-third-party.md#mit-license). -For individual contributions to the project, please confer the [Individual Contributor License Agreement](https://github.com/NVlabs/flip/blob/main/flip_evaluator/misc/CLA.md). +For individual contributions to the project, please confer the [Individual Contributor License Agreement](https://github.com/NVlabs/flip/blob/main/misc/CLA.md). For business inquiries, please visit our website and submit the form: [NVIDIA Research Licensing](https://www.nvidia.com/en-us/research/inquiries/). From ae785ba0ece1461dd7a318a505edccc97d22325c Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Mon, 11 Nov 2024 10:53:24 +0100 Subject: [PATCH 20/32] Added manylinux_x86_64 to wheels --- .github/workflows/flip-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/flip-deploy.yml b/.github/workflows/flip-deploy.yml index 4e1fe7f..39a6225 100644 --- a/.github/workflows/flip-deploy.yml +++ b/.github/workflows/flip-deploy.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: # macos-13 is an intel runner, macos-14 is apple silicon - os: [ubuntu-latest, windows-latest, macos-13, macos-14] + os: [ubuntu-latest, manylinux_x86_64-latest, windows-latest, macos-13, macos-14] python: [cp38, cp39, cp310, cp311, cp312, cp312_stable, cp313] exclude: # The first Python version to target Apple arm64 architectures is 3.9. From b635250c35ce3e145bcbf128665a34909046bd38 Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Mon, 11 Nov 2024 11:12:39 +0100 Subject: [PATCH 21/32] No more manylinux --- .github/workflows/flip-deploy.yml | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/flip-deploy.yml b/.github/workflows/flip-deploy.yml index 39a6225..4e1fe7f 100644 --- a/.github/workflows/flip-deploy.yml +++ b/.github/workflows/flip-deploy.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: # macos-13 is an intel runner, macos-14 is apple silicon - os: [ubuntu-latest, manylinux_x86_64-latest, windows-latest, macos-13, macos-14] + os: [ubuntu-latest, windows-latest, macos-13, macos-14] python: [cp38, cp39, cp310, cp311, cp312, cp312_stable, cp313] exclude: # The first Python version to target Apple arm64 architectures is 3.9. diff --git a/pyproject.toml b/pyproject.toml index ee529b0..ceb2e7c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ build-backend = "scikit_build_core.build" [project] name = "flip_evaluator" -version = "1.5.5" +version = "1.5.6" description = "A Difference Evaluator for Alternating Images" readme = "README.md" requires-python = ">=3.8" From 36c08c0e93d0f4dd66b2936d8f0749aaa0484101 Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Mon, 11 Nov 2024 12:40:40 +0100 Subject: [PATCH 22/32] Final version update --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ceb2e7c..777f00f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ build-backend = "scikit_build_core.build" [project] name = "flip_evaluator" -version = "1.5.6" +version = "1.5" description = "A Difference Evaluator for Alternating Images" readme = "README.md" requires-python = ">=3.8" From 8c317c5caa036defe4b6282d741c934135405eb6 Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Mon, 11 Nov 2024 12:42:21 +0100 Subject: [PATCH 23/32] Minor fix --- misc/versionList.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/misc/versionList.md b/misc/versionList.md index fa366dd..954187f 100644 --- a/misc/versionList.md +++ b/misc/versionList.md @@ -7,7 +7,7 @@ changed for the different versions of FLIP: - Flipped the ꟻ in ꟻLIP. The entire name (FLIP) should now be readable on all devices. - Published Python version of FLIP to PyPI (URL: https://pypi.org/project/flip-evaluator/). - The Python version of FLIP (tool and API) is now installed by `pip install flip-evaluator`. - - The distribution has been tested on Windows, Linux (Ubuntu 24.04), and OS X ($\ge$ 10.15). Wheels are built for each (and various CPython versions $\ge$ 3.8) using [cibuildwheel](https://github.com/pypa/cibuildwheel). Note that FLIP's output might differ slightly between the different operative systems. The references used for `flip_evaluator/tests/test.py` are made for Windows. While the mean tests (means compared up to six decimal points) pass on each mentioned operative system, not all error map pixels are identical. + - The distribution has been tested on Windows, Linux (Ubuntu 24.04), and OS X ($\ge$ 10.15). Wheels are built for each (and various CPython versions $\ge$ 3.8) using [cibuildwheel](https://github.com/pypa/cibuildwheel). Note that FLIP's output might differ slightly between the different operative systems. The references used for `src/tests/test.py` are made for Windows. While the mean tests (means compared up to six decimal points) pass on each mentioned operative system, not all error map pixels are identical. - After installation, the tool can be run directly in a shell by `flip --reference reference.{png|exr} --test test.{png|exr}`. - After installation, the FLIP API is available in Python by `import flip_evaluator as flip`. - Python version is now built using `scikit` instead of `setuptools`, and uses [nanobind](https://github.com/wjakob/nanobind) instead of [pybind11](https://github.com/pybind/pybind11). From 1bf3fe7a0f9ce113df1978bd3107565972f24b76 Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Mon, 11 Nov 2024 13:12:30 +0100 Subject: [PATCH 24/32] Changed to 1.6 due to PyPI naming conflict --- README.md | 4 ++-- misc/versionList.md | 5 ++++- pyproject.toml | 2 +- src/cpp/README.md | 2 +- src/cpp/tool/FLIPToolHelpers.h | 2 +- src/python/README.md | 2 +- src/pytorch/README.md | 2 +- 7 files changed, 11 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f5eb25c..efef05c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![Teaser image](images/teaser.png "Teaser image") -# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.5) +# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.6) By [Pontus Ebelin](https://research.nvidia.com/person/pontus-ebelin) @@ -27,7 +27,7 @@ The changes made for the different versions of FLIP are summarized in the [versi [An image gallery](https://research.nvidia.com/node/3525) displaying a large quantity of reference/test images and corresponding error maps from different metrics. -**Note**: since v1.5, the Python version of FLIP can now be installed via `pip install flip-evaluator`. +**Note**: since v1.6, the Python version of FLIP can now be installed via `pip install flip-evaluator`. **Note**: in v1.3, we switched to a *single header* ([FLIP.h](src/cpp/FLIP.h)) for C++/CUDA for easier integration. diff --git a/misc/versionList.md b/misc/versionList.md index 954187f..7936ecb 100644 --- a/misc/versionList.md +++ b/misc/versionList.md @@ -3,7 +3,7 @@ In addition to various minor changes, the following was changed for the different versions of FLIP: -# Version 1.5 (commit ?) +# Version 1.6 (commit ?) - Flipped the ꟻ in ꟻLIP. The entire name (FLIP) should now be readable on all devices. - Published Python version of FLIP to PyPI (URL: https://pypi.org/project/flip-evaluator/). - The Python version of FLIP (tool and API) is now installed by `pip install flip-evaluator`. @@ -15,6 +15,9 @@ changed for the different versions of FLIP: - Updated Python/C++/CUDA test script. - Various significant bugfixes. +# Version 1.5 (commit -) +- Skipped version 1.5 due to PyPI-related mistake. Version 1.6 is the same as version 1.5 was supposed to be. + # Version 1.4 (commits 6265f80 to 0349494) - Changed the Python version of FLIP so that it leverages the C++ code through [pybind11](https://github.com/pybind/pybind11). - Results (only evaluation, not including file load/save, etc; measured on an AMD Ryzen Threadripper 3970X 32-Core Processor, 3693 MHz, with 32 Cores and 64 Logical Processors): diff --git a/pyproject.toml b/pyproject.toml index 777f00f..08710ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ build-backend = "scikit_build_core.build" [project] name = "flip_evaluator" -version = "1.5" +version = "1.6" description = "A Difference Evaluator for Alternating Images" readme = "README.md" requires-python = ">=3.8" diff --git a/src/cpp/README.md b/src/cpp/README.md index 7429f75..fd0e769 100644 --- a/src/cpp/README.md +++ b/src/cpp/README.md @@ -1,4 +1,4 @@ -# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.5) +# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.6) By [Pontus Ebelin](https://research.nvidia.com/person/pontus-ebelin) diff --git a/src/cpp/tool/FLIPToolHelpers.h b/src/cpp/tool/FLIPToolHelpers.h index d2ce0af..d5a4719 100644 --- a/src/cpp/tool/FLIPToolHelpers.h +++ b/src/cpp/tool/FLIPToolHelpers.h @@ -480,7 +480,7 @@ namespace FLIPTool std::string FLIPString = "FLIP"; int MajorVersion = 1; - int MinorVersion = 5; + int MinorVersion = 6; if (commandLine.optionSet("help")) { diff --git a/src/python/README.md b/src/python/README.md index 6a1df10..cad5b12 100644 --- a/src/python/README.md +++ b/src/python/README.md @@ -1,4 +1,4 @@ -# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.5) +# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.6) By [Pontus Ebelin](https://research.nvidia.com/person/pontus-ebelin) diff --git a/src/pytorch/README.md b/src/pytorch/README.md index 14c2f01..5de1ec7 100644 --- a/src/pytorch/README.md +++ b/src/pytorch/README.md @@ -1,4 +1,4 @@ -# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.5) +# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.6) By [Pontus Ebelin](https://research.nvidia.com/person/pontus-ebelin) From 07aa5d420949b637e2449eb73da958b4250ba174 Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Mon, 1 Sep 2025 09:23:59 +0200 Subject: [PATCH 25/32] Updated GitHub workflow --- .github/workflows/flip-deploy.yml | 4 ++-- .github/workflows/flip_ci.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/flip-deploy.yml b/.github/workflows/flip-deploy.yml index 4e1fe7f..6f25ac6 100644 --- a/.github/workflows/flip-deploy.yml +++ b/.github/workflows/flip-deploy.yml @@ -47,9 +47,9 @@ jobs: run: | python -m cibuildwheel --output-dir wheelhouse - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: - name: wheels + name: wheels-${{ matrix.os }}-${{ matrix.python }} path: ./wheelhouse/*.whl build_sdist: diff --git a/.github/workflows/flip_ci.yml b/.github/workflows/flip_ci.yml index 06f3d43..c46f46a 100644 --- a/.github/workflows/flip_ci.yml +++ b/.github/workflows/flip_ci.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Checkout Sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install CUDA if: ${{ matrix.os == 'ubuntu-latest' }} From 38bf8e73d6eb86532f3bafa28ed94a9d0d0bd7c3 Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Fri, 7 Nov 2025 10:51:29 +0100 Subject: [PATCH 26/32] Fixed memory leak --- src/cpp/tool/imagehelpers.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpp/tool/imagehelpers.h b/src/cpp/tool/imagehelpers.h index 43a4022..0c0a0fd 100644 --- a/src/cpp/tool/imagehelpers.h +++ b/src/cpp/tool/imagehelpers.h @@ -255,6 +255,7 @@ namespace ImageHelpers if (loadImage(fileName, imgWidth, imgHeight, pixels)) { dstImage.setPixels(pixels, imgWidth, imgHeight); + delete[] pixels; return true; } return false; @@ -343,16 +344,15 @@ namespace ImageHelpers const char* error; int ret = SaveEXRImageToFile(&exrImage, &exrHeader, fileName.c_str(), &error); + free(exrHeader.channels); + free(exrHeader.pixel_types); + free(exrHeader.requested_pixel_types); if (ret != TINYEXR_SUCCESS) { std::cerr << "Failed to save EXR file <" << fileName << ">: " << error << "\n"; return false; } - free(exrHeader.channels); - free(exrHeader.pixel_types); - free(exrHeader.requested_pixel_types); - return true; } } \ No newline at end of file From 75471e2d97101b38344b4e277ebceb6d822efbda Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Fri, 7 Nov 2025 10:51:59 +0100 Subject: [PATCH 27/32] Fixed HDR-FLIP crash when median lum. is 0 --- src/cpp/FLIP.h | 1 + src/pytorch/flip_loss.py | 1 + 2 files changed, 2 insertions(+) diff --git a/src/cpp/FLIP.h b/src/cpp/FLIP.h index 232d72a..5987fd8 100644 --- a/src/cpp/FLIP.h +++ b/src/cpp/FLIP.h @@ -2228,6 +2228,7 @@ namespace FLIP size_t medianLocation = luminances.size() / 2; std::nth_element(luminances.begin(), luminances.begin() + medianLocation, luminances.end()); float Ymedian = luminances[medianLocation]; + Ymedian = std::max(Ymedian, std::numeric_limits::epsilon()); // Avoid median = 0 when more than half of the image's pixels are black. startExposure = log2(xMax / Ymax); stopExposure = log2(xMax / Ymedian); diff --git a/src/pytorch/flip_loss.py b/src/pytorch/flip_loss.py index e63a15a..bd85c1a 100644 --- a/src/pytorch/flip_loss.py +++ b/src/pytorch/flip_loss.py @@ -383,6 +383,7 @@ def compute_start_stop_exposures(reference, tone_mapper, tmax, tmin): dim = Y_reference.size() Y_ref = Y_reference.view(dim[0], dim[1], dim[2]*dim[3]) Y_lo = torch.median(Y_ref, dim=2).values.unsqueeze(2).unsqueeze(3) + Y_lo = torch.clamp(Y_lo, min=1.192092896e-07) # Avoid median = 0 when more than half of the image's pixels are black. stop_exposure = torch.log2(x_min / Y_lo) return start_exposure, stop_exposure From 2e40cc63fcca257bbbabb8d0bc5363112014724c Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Fri, 7 Nov 2025 11:15:42 +0100 Subject: [PATCH 28/32] Update to FLIP v1.7 --- README.md | 4 +++- misc/versionList.md | 7 ++++++- pyproject.toml | 2 +- src/cpp/README.md | 2 +- src/cpp/tool/FLIPToolHelpers.h | 2 +- src/python/README.md | 2 +- src/pytorch/README.md | 2 +- 7 files changed, 14 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index efef05c..09346b6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![Teaser image](images/teaser.png "Teaser image") -# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.6) +# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.7) By [Pontus Ebelin](https://research.nvidia.com/person/pontus-ebelin) @@ -27,6 +27,8 @@ The changes made for the different versions of FLIP are summarized in the [versi [An image gallery](https://research.nvidia.com/node/3525) displaying a large quantity of reference/test images and corresponding error maps from different metrics. +**Note**: since v1.7, the automatic stop exposure in HDR-FLIP is able to handle reference images whose median luminance is 0. + **Note**: since v1.6, the Python version of FLIP can now be installed via `pip install flip-evaluator`. **Note**: in v1.3, we switched to a *single header* ([FLIP.h](src/cpp/FLIP.h)) for C++/CUDA for easier integration. diff --git a/misc/versionList.md b/misc/versionList.md index 7936ecb..27bb830 100644 --- a/misc/versionList.md +++ b/misc/versionList.md @@ -3,7 +3,12 @@ In addition to various minor changes, the following was changed for the different versions of FLIP: -# Version 1.6 (commit ?) +# Version 1.7 (commit ?) +- Fixed memory leaks in the C++/CUDA/Python versions of FLIP. +- HDR-FLIP: Fixed crashes that followed from the reference's median being 0. + - Automatic start and stop exposures in HDR-FLIP are computed using statistics of the reference image. For the stop exposure, we use the median luminance of the reference. When that is 0, we used to get undefined behavior or a crash. Version 1.7 fixes this by clamping the median to have a minimum value of [FLT_EPSILON](https://learn.microsoft.com/en-us/cpp/c-language/limits-on-floating-point-constants?view=msvc-170). + +# Version 1.6 (commit 7967578) - Flipped the ꟻ in ꟻLIP. The entire name (FLIP) should now be readable on all devices. - Published Python version of FLIP to PyPI (URL: https://pypi.org/project/flip-evaluator/). - The Python version of FLIP (tool and API) is now installed by `pip install flip-evaluator`. diff --git a/pyproject.toml b/pyproject.toml index 08710ba..8077e35 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ build-backend = "scikit_build_core.build" [project] name = "flip_evaluator" -version = "1.6" +version = "1.7" description = "A Difference Evaluator for Alternating Images" readme = "README.md" requires-python = ">=3.8" diff --git a/src/cpp/README.md b/src/cpp/README.md index fd0e769..d09eda1 100644 --- a/src/cpp/README.md +++ b/src/cpp/README.md @@ -1,4 +1,4 @@ -# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.6) +# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.7) By [Pontus Ebelin](https://research.nvidia.com/person/pontus-ebelin) diff --git a/src/cpp/tool/FLIPToolHelpers.h b/src/cpp/tool/FLIPToolHelpers.h index d5a4719..49537b4 100644 --- a/src/cpp/tool/FLIPToolHelpers.h +++ b/src/cpp/tool/FLIPToolHelpers.h @@ -480,7 +480,7 @@ namespace FLIPTool std::string FLIPString = "FLIP"; int MajorVersion = 1; - int MinorVersion = 6; + int MinorVersion = 7; if (commandLine.optionSet("help")) { diff --git a/src/python/README.md b/src/python/README.md index cad5b12..4a07f8e 100644 --- a/src/python/README.md +++ b/src/python/README.md @@ -1,4 +1,4 @@ -# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.6) +# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.7) By [Pontus Ebelin](https://research.nvidia.com/person/pontus-ebelin) diff --git a/src/pytorch/README.md b/src/pytorch/README.md index 5de1ec7..7dfabda 100644 --- a/src/pytorch/README.md +++ b/src/pytorch/README.md @@ -1,4 +1,4 @@ -# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.6) +# FLIP: A Tool for Visualizing and Communicating Errors in Rendered Images (v1.7) By [Pontus Ebelin](https://research.nvidia.com/person/pontus-ebelin) From c700f274077eefe94e777611f42a6f90eeb00463 Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Fri, 7 Nov 2025 11:27:14 +0100 Subject: [PATCH 29/32] Update git workflows --- .github/workflows/flip-deploy.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/flip-deploy.yml b/.github/workflows/flip-deploy.yml index 6f25ac6..04c05ad 100644 --- a/.github/workflows/flip-deploy.yml +++ b/.github/workflows/flip-deploy.yml @@ -16,12 +16,11 @@ jobs: build_wheels: strategy: matrix: - # macos-13 is an intel runner, macos-14 is apple silicon - os: [ubuntu-latest, windows-latest, macos-13, macos-14] + os: [ubuntu-latest, windows-latest, macos-latest] python: [cp38, cp39, cp310, cp311, cp312, cp312_stable, cp313] exclude: # The first Python version to target Apple arm64 architectures is 3.9. - - os: macos-14 + - os: [macos-latest] python: cp38 name: > ${{ matrix.python }} wheel for ${{ matrix.os }} From 323fcc1f5418625dadd8c259006dab522cd38979 Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Fri, 7 Nov 2025 14:55:06 +0100 Subject: [PATCH 30/32] Fix merge conflict bug --- src/CMakeLists.txt | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 583fc74..6476f1e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -30,51 +30,6 @@ # SPDX-License-Identifier: BSD-3-Clause ################################################################################# -<<<<<<<< HEAD:pyproject.toml -[build-system] -requires = ["scikit-build-core >=0.4.3", "nanobind >=1.3.2"] -build-backend = "scikit_build_core.build" - -[project] -name = "flip_evaluator" -version = "1.7" -description = "A Difference Evaluator for Alternating Images" -readme = "README.md" -requires-python = ">=3.8" -authors = [ - { name = "Pontus Ebelin" }, - { name = "Tomas Akenine-Möller" } -] -classifiers = [ - "License :: OSI Approved :: BSD License" -] - -[project.scripts] -flip = "flip_evaluator.flip_python_api:main" - -[project.urls] -Homepage = "https://github.com/nvlabs/flip" - -[tool.cibuildwheel] -build-verbosity = 1 -build = ["cp38-*", "cp39-*", "cp310-*", "cp311-*", "cp312-*", "cp313-*"] -test-command = ["flip -h"] - -[tool.cibuildwheel.macos.environment] -MACOSX_DEPLOYMENT_TARGET = "10.15" - -[tool.scikit-build] -minimum-version = "0.4" -sdist.include = ["src/flip_evaluator/__init__.py", "src/flip_evaluator/flip_python_api.py", "src/cpp/FLIP.h", "src/cpp/tool/*.h"] -sdist.exclude = [".github", ".gitignore", "images", "misc", "dist", "*__pycache__*", "src/pytorch", "src/cmake", "src/tests", "src/CMakeLists.txt", "src/python", "src/cpp/FLIP.sln", "src/cpp/CMakeLists.txt", "src/cpp/README.md", "src/cpp/tool/CMakeLists.txt", "src/cpp/tool/CPP.vcxproj*", "src/cpp/tool/CUDA.vcxproj*", "src/cpp/tool/*.cpp", "src/cpp/tool/*.cu"] - -[tool.hatch.metadata.hooks.fancy-pypi-readme] -content-type = "text/markdown" - -build-dir = "build/{wheel_tag}" - -wheel.py-api = "cp312" -======== cmake_minimum_required(VERSION 3.9) set(CMAKE_DISABLE_SOURCE_CHANGES ON) @@ -94,4 +49,3 @@ include(GNUInstallDirs) option(FLIP_ENABLE_CUDA "Include CUDA version of flip" OFF) add_subdirectory(cpp) ->>>>>>>> upstream/main:src/CMakeLists.txt From 63c4dcfd0552ac097f6bd575c4c0ed93d6d16d5a Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Fri, 7 Nov 2025 15:01:34 +0100 Subject: [PATCH 31/32] Fixed more merge conflict bugs --- src/cpp/README.md | 5 +++-- src/cpp/tool/FLIPToolHelpers.h | 18 +++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/cpp/README.md b/src/cpp/README.md index d09eda1..991d51d 100644 --- a/src/cpp/README.md +++ b/src/cpp/README.md @@ -26,7 +26,7 @@ Since v1.4, the majority of the code for the tool is contained in [FLIPToolHelpe # License -Copyright © 2020-2024, NVIDIA Corporation & Affiliates. All rights reserved. +Copyright © 2020-2025, NVIDIA Corporation & Affiliates. All rights reserved. This work is made available under a [BSD 3-Clause License](https://github.com/NVlabs/flip/blob/main/LICENSE). @@ -50,9 +50,10 @@ For business inquiries, please visit our website and submit the form: [NVIDIA Re ``` - The FLIP.sln solution contains one CUDA backend project and one pure C++ backend project for the FLIP tool. - Compiling the CUDA project requires a CUDA compatible GPU. Instruction on how to install CUDA can be found [here](https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/index.html). -- Alternatively, a CMake build can be done by creating a build directory and invoking CMake on the source `cpp` dir (add `--config Release` to build release configuration on Windows): +- Alternatively, a CMake build can be done by creating a build directory in the `src` directory and invoking CMake on the source `cpp` directory (add `--config Release` to build release configuration on Windows): ``` + cd src mkdir build cd build cmake .. diff --git a/src/cpp/tool/FLIPToolHelpers.h b/src/cpp/tool/FLIPToolHelpers.h index 49537b4..6c7a9cd 100644 --- a/src/cpp/tool/FLIPToolHelpers.h +++ b/src/cpp/tool/FLIPToolHelpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * Copyright (c) 2020-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -26,7 +26,7 @@ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * SPDX-FileCopyrightText: Copyright (c) 2020-2024 NVIDIA CORPORATION & AFFILIATES + * SPDX-FileCopyrightText: Copyright (c) 2020-2025 NVIDIA CORPORATION & AFFILIATES * SPDX-License-Identifier: BSD-3-Clause */ @@ -490,17 +490,17 @@ namespace FLIPTool } if (!commandLine.optionSet("reference")) { - std::cout << "Error: you need to set a reference image filename.\n Typically done with '-r refimg.{png,exr}' or '--reference refimg.{png,exr}'.\n Use -h or --help for help message. Exiting\n"; + std::cout << "Error: you need to set a reference image filename.\n Typically done with '-r refimg.{png,exr}' or '--reference refimg.{png,exr}'.\n Use -h or --help for help message. Exiting.\n"; exit(EXIT_FAILURE); } if (!std::filesystem::exists(commandLine.getOptionValue("reference"))) // Reference does not exist? { - std::cout << "Error: reference file <" << commandLine.getOptionValue("reference") << "> does not exist. Exiting\n"; + std::cout << "Error: reference file <" << commandLine.getOptionValue("reference") << "> does not exist. Exiting.\n"; exit(EXIT_FAILURE); } if (!commandLine.optionSet("test")) { - std::cout << "Error: you need to set a test image filename.\n Typically done with '-t testimg.{png,exr}' or '--test testimg.{png,exr}'.\n Use -h or --help for help message. Exiting\n"; + std::cout << "Error: you need to set a test image filename.\n Typically done with '-t testimg.{png,exr}' or '--test testimg.{png,exr}'.\n Use -h or --help for help message. Exiting.\n"; exit(EXIT_FAILURE); } if ((commandLine.optionSet("basename") && commandLine.getOptionValues("test").size() != 1) || commandLine.getError()) @@ -543,7 +543,7 @@ namespace FLIPTool bool refImageOk = ImageHelpers::load(referenceImage, referenceFileName.toString()); // Load reference image. if (!refImageOk) { - std::cout << "Error: could not read reference image file <" << referenceFileName.toString() << ">. Exiting\n"; + std::cout << "Error: could not read reference image file <" << referenceFileName.toString() << ">. Note that FLIP only loads png, bmp, tga, and exr images. Exiting.\n"; exit(EXIT_FAILURE); } @@ -569,7 +569,7 @@ namespace FLIPTool if (!std::filesystem::exists(testFileName.toString())) { - std::cout << "Error: test image file <" << testFileName.toString() << "> does not exist. Exiting\n"; + std::cout << "Error: test image file <" << testFileName.toString() << "> does not exist. Exiting.\n"; exit(EXIT_FAILURE); } @@ -577,12 +577,12 @@ namespace FLIPTool bool testImageOk = ImageHelpers::load(testImage, testFileName.toString()); // Load test image. if (!testImageOk) { - std::cout << "Error: could not read test file <" << testFileName.toString() << ">. Exiting\n"; + std::cout << "Error: could not read test file <" << testFileName.toString() << ">. Note that FLIP only loads png, bmp, tga, and exr images. Exiting.\n"; exit(EXIT_FAILURE); } if (referenceImage.getWidth() != testImage.getWidth() || referenceImage.getHeight() != testImage.getHeight()) { - std::cout << "Error: reference <" << referenceImage.getWidth() << "x" << referenceImage.getHeight() << "> and test <" << testImage.getWidth() << "x" << testImage.getHeight() << "> images must be of equal dimensions. Exiting\n"; + std::cout << "Error: reference <" << referenceImage.getWidth() << "x" << referenceImage.getHeight() << "> and test <" << testImage.getWidth() << "x" << testImage.getHeight() << "> images must be of equal dimensions. Exiting.\n"; exit(EXIT_FAILURE); } From 51c0eef179d4e634a1d745491fff86c3d691b35b Mon Sep 17 00:00:00 2001 From: Pontus Ebelin Date: Fri, 7 Nov 2025 15:18:53 +0100 Subject: [PATCH 32/32] [PyTorch] Updated float eps value in median computation --- README.md | 2 +- src/pytorch/flip_loss.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2708f2e..9bb3672 100644 --- a/README.md +++ b/README.md @@ -138,4 +138,4 @@ Should your work use the FLIP tool in a more general fashion, please cite the Ra # Acknowledgements We appreciate the following peoples' contributions to this repository: -Jonathan Granskog, Jacob Munkberg, Jon Hasselgren, Jefferson Amstutz, Alan Wolfe, Killian Herveau, Vinh Truong, Philippe Dagobert, Hannes Hergeth, Matt Pharr, Tizian Zeltner, Jan Honsbrok, Chris Zhang, Wenzel Jakob, and Julian Amann. +Jonathan Granskog, Jacob Munkberg, Jon Hasselgren, Jefferson Amstutz, Alan Wolfe, Killian Herveau, Vinh Truong, Philippe Dagobert, Hannes Hergeth, Matt Pharr, Tizian Zeltner, Jan Honsbrok, Chris Zhang, Wenzel Jakob, Julian Amann, and Xijie Yang. diff --git a/src/pytorch/flip_loss.py b/src/pytorch/flip_loss.py index bd85c1a..687fb71 100644 --- a/src/pytorch/flip_loss.py +++ b/src/pytorch/flip_loss.py @@ -383,7 +383,7 @@ def compute_start_stop_exposures(reference, tone_mapper, tmax, tmin): dim = Y_reference.size() Y_ref = Y_reference.view(dim[0], dim[1], dim[2]*dim[3]) Y_lo = torch.median(Y_ref, dim=2).values.unsqueeze(2).unsqueeze(3) - Y_lo = torch.clamp(Y_lo, min=1.192092896e-07) # Avoid median = 0 when more than half of the image's pixels are black. + Y_lo = torch.clamp(Y_lo, min=torch.finfo(torch.float32).eps) # Avoid median = 0 when more than half of the image's pixels are black. stop_exposure = torch.log2(x_min / Y_lo) return start_exposure, stop_exposure