#ifndef HAADER_ILUCF4Z0 #define HAADER_ILUCF4Z0 #include #include "image.h" namespace haader { class ResponseFunction { friend class InverseResponseFunction; public: // Returns a pixel value (0-255) given the logarithm of a luminance value. int lookup(double value) const; private: // minimum log of luminance value double m_min_value; // maximum log of luminance value double m_max_value; // Precomputed value: // 1.0 / (m_max_value - m_min_value) double m_recip_range; // Response function is implemented as a lookup table of with 256 values std::vector m_lookup_table; }; class InverseResponseFunction { friend class HdrImageStack; public: // Return logarithm of luminance given a pixel value (0-255) double lookup(int index) const; // The inverse of the lookup function: // y == lookup(x) -> x == inverse_lookup(y) // O(n) complexity, proportional to size of lookup table. int inverse_lookup(double value) const; // Construct a ResponseFunction object that allows efficient O(1) inverse_lookup. // bins: Size of the lookup table for the response function ResponseFunction to_response_function(int bins=1024); private: // Returns true if a monotonically increasing lookup table without missing values // can be constructed. bool repair(); // Remove missing values by linear interpolation of neighboring values void fill_zeros(); // Apply binomial low pass filter void low_pass_filter(); // Returns true if values are monotonically increasing bool is_monotonic(); // Inverse response function is implemented as a lookup table with 256 values std::vector m_lookup_table; }; // High Dynamic Range Image. // Stores the logarithm of the scene luminance for each pixel/channel in a high resolution. class HdrImage { friend class HdrImageStack; public: HdrImage(); // Construct low dynamic range image with the logarithm of the scene luminance. Image get_log_image(); // Construct low dynamic range image by a simulated exposure with a given response function. // exposure_time: Exposure time in seconds // compression: // A value > 1.0 will compress the luminace values and give more contrast. // A value < 1.0 will reduce the contrast but lower the risk of // under-/overexposure in parts of the image. Image expose(double exposure_time, const ResponseFunction &rf, double compression=1.0); private: // Pixel values (logarithm of scene luminance). The channels are interleaved (RGBRGBRGB...). std::vector m_image_data; // Width in pixels unsigned int m_width; // Height in pixels unsigned int m_height; // Number of channels (usually 3 for RGB images) unsigned int m_components; }; // A stack of images/photographs of the same scene, with the same resolution but different exposure times. class HdrImageStack { public: HdrImageStack(); // Read images from the given array of file paths bool read_from_files(char * const* file_paths, int number_of_paths); bool get_average_image(Image &output); bool get_average_image_slow(Image &output); // Approximate the inverse response function from samples of random pixel locations. // num_samples: Number of samples // Returns true if a well-formed inverse response function could be found. bool get_inverse_response_function(InverseResponseFunction &output, unsigned int num_samples); // Return a HDR-image given an inverse response function HdrImage get_hdr_image(const InverseResponseFunction &invRespFunc); private: // Sort the images by exposure time void sort_by_exposure(); // The images std::vector m_images; }; } #endif // HAADER_ILUCF4Z0