1 // This file comes from the original BCD implementation,
2 // with minor changes to remove dependencies, unused code
3 // and re-formatting. Original license follows:
4 
5 // This file is part of the reference implementation for the paper
6 //   Bayesian Collaborative Denoising for Monte-Carlo Rendering
7 //   Malik Boughida and Tamy Boubekeur.
8 //   Computer Graphics Forum (Proc. EGSR 2017), vol. 36, no. 4, p. 137-153, 2017
9 //
10 // All rights reserved. Use of this source code is governed by a
11 // BSD-style license that can be found in the LICENSE.txt file.
12 
13 #ifndef DENOISER_H
14 #define DENOISER_H
15 
16 // BCD headers.
17 #include "DeepImage.h"
18 #include "IDenoiser.h"
19 
20 // Boost headers.
21 #include "boost/atomic/atomic.hpp"
22 
23 // Standard headers.
24 #include <memory>
25 #include <vector>
26 
27 namespace bcd
28 {
29 
30 class PixelPosition;
31 
32 //  Class to implement the monoscale Bayesian Collaborative Filtering for Monte-Carlo Rendering
33 class Denoiser
34   : public IDenoiser
35 {
36   public:
~Denoiser()37     virtual ~Denoiser() {}
38 
39     virtual bool denoise();
40 
getNbOfSamplesSqrtImage()41     const Deepimf& getNbOfSamplesSqrtImage() const
42     {
43         return m_nbOfSamplesSqrtImage;
44     }
45 
getPixelCovarianceImage()46     const Deepimf& getPixelCovarianceImage() const
47     {
48         return m_pixelCovarianceImage;
49     }
50 
getOutputSummedColorImage(int i_index)51     Deepimf& getOutputSummedColorImage(int i_index)
52     {
53         return m_outputSummedColorImages[i_index];
54     }
55 
getEstimatesCountImage(int i_index)56     DeepImage<int>& getEstimatesCountImage(int i_index)
57     {
58         return m_estimatesCountImages[i_index];
59     }
60 
getIsCenterOfAlreadyDenoisedPatchImage()61     DeepImage<bool>& getIsCenterOfAlreadyDenoisedPatchImage()
62     {
63         return m_isCenterOfAlreadyDenoisedPatchImage;
64     }
65 
getImagesWidth()66     int getImagesWidth() const
67     {
68         return m_width;
69     }
70 
getImagesHeight()71     int getImagesHeight() const
72     {
73         return m_height;
74     }
75 
76   private:
77     int                         m_width;
78     int                         m_height;
79     int                         m_nbOfPixels;
80     Deepimf                     m_nbOfSamplesSqrtImage;
81     Deepimf                     m_pixelCovarianceImage;
82     std::vector<Deepimf>        m_outputSummedColorImages;
83     std::vector<DeepImage<int>> m_estimatesCountImages;
84     DeepImage<bool>             m_isCenterOfAlreadyDenoisedPatchImage; // For the "marking strategy"
85 
86     void doDenoise(
87         std::vector<PixelPosition>::const_iterator  i_pixelBegin,
88         std::vector<PixelPosition>::const_iterator  i_pixelEnd,
89         const std::size_t                           i_totalNbOfPixels,
90         boost::atomic<int>&                         i_nbOfPixelsComputed,
91         const std::size_t                           i_threadIndex,
92         bool&                                       i_abortRequested);
93 
94     void computeNbOfSamplesSqrt();
95     void computePixelCovFromSampleCov();
96 
97     void reorderPixelSet(
98         std::vector<PixelPosition>& io_rPixelSet) const; // Reorders the pixel set
99 
100     // Reorders the pixel by cutting the image in horizontal strips,
101     // and scanning the strips in the order 1, 3, 5, 7, ... 2, 4, 6, 8, ...
102     void reorderPixelSetJumpNextStrip(
103         std::vector<PixelPosition>& io_rPixelSet) const;
104 
105     static void reorderPixelSetJumpNextChunk(
106         std::vector<PixelPosition>& io_rPixelSet,
107         int                         i_chunkSize);
108 
109     static void reorderPixelSetShuffle(
110         std::vector<PixelPosition>& io_rPixelSet); // Totally random reordering
111 
112     void finalAggregation();
113 
114     void fixNegativeInfNaNValues();
115     void markNegativeInfNaNValues();
116 };
117 
118 } // namespace bcd
119 
120 #endif // DENOISER_H
121