A tool to construct HDR-images from a series of exposures.

haader.h 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #ifndef HAADER_ILUCF4Z0
  2. #define HAADER_ILUCF4Z0
  3. #include <vector>
  4. #include <iostream>
  5. #include "image.h"
  6. namespace haader {
  7. class ResponseFunction {
  8. friend class InverseResponseFunction;
  9. public:
  10. // Returns a pixel value (0-255) given the logarithm of a luminance value.
  11. int lookup(double value) const;
  12. // Write the lookup table in CSV-format to the given stream
  13. void to_csv_stream(std::ostream &stream) const;
  14. private:
  15. // minimum log of luminance value
  16. double m_min_value;
  17. // maximum log of luminance value
  18. double m_max_value;
  19. // Precomputed value:
  20. // 1.0 / (m_max_value - m_min_value)
  21. double m_recip_range;
  22. // Response function is implemented with a lookup table
  23. std::vector<int> m_lookup_table;
  24. };
  25. class InverseResponseFunction {
  26. friend class HdrImageStack;
  27. public:
  28. // Return logarithm of luminance given a pixel value (0-255)
  29. double lookup(int index) const;
  30. // The inverse of the lookup function:
  31. // y == lookup(x) -> x == inverse_lookup(y)
  32. // O(n) complexity, proportional to size of lookup table.
  33. int inverse_lookup(double value) const;
  34. // Construct a ResponseFunction object that allows efficient O(1) inverse_lookup.
  35. // bins: Size of the lookup table for the response function
  36. ResponseFunction to_response_function(int bins=1024);
  37. // Write the lookup table in CSV-format to the given stream
  38. void to_csv_stream(std::ostream &stream) const;
  39. private:
  40. // Returns true if a monotonically increasing lookup table without missing values
  41. // can be constructed.
  42. bool repair();
  43. // Remove missing values by linear interpolation of neighboring values
  44. void fill_zeros();
  45. // Apply binomial low pass filter
  46. void low_pass_filter();
  47. // Returns true if values are monotonically increasing
  48. bool is_monotonic();
  49. // Inverse response function is implemented as a lookup table with 256 values
  50. std::vector<double> m_lookup_table;
  51. };
  52. class Histogram {
  53. public:
  54. std::vector<unsigned int> m_bins;
  55. double m_min_value;
  56. double m_max_value;
  57. unsigned int m_max_freq;
  58. };
  59. // High Dynamic Range Image.
  60. // Stores the logarithm of the scene luminance for each pixel/channel in a high resolution.
  61. class HdrImage {
  62. friend class HdrImageStack;
  63. public:
  64. HdrImage();
  65. // Construct low dynamic range image with the logarithm of the scene luminance.
  66. Image get_log_image();
  67. // Construct low dynamic range image by a simulated exposure with a given response function.
  68. // exposure_time: Exposure time in seconds
  69. // compression:
  70. // A value > 1.0 will compress the luminace values and give more contrast.
  71. // A value < 1.0 will reduce the contrast but lower the risk of
  72. // under-/overexposure in parts of the image.
  73. Image expose(double exposure_time, const ResponseFunction &rf, double compression=1.0);
  74. Histogram histogram(unsigned int number_of_bins) const;
  75. private:
  76. // Pixel values (logarithm of scene luminance). The channels are interleaved (RGBRGBRGB...).
  77. std::vector<double> m_image_data;
  78. // Width in pixels
  79. unsigned int m_width;
  80. // Height in pixels
  81. unsigned int m_height;
  82. // Number of channels (usually 3 for RGB images)
  83. unsigned int m_components;
  84. };
  85. // A stack of images/photographs of the same scene, with the same resolution but different exposure times.
  86. class HdrImageStack {
  87. public:
  88. HdrImageStack();
  89. // Read images from the given array of file paths
  90. bool read_from_files(char * const* file_paths, int number_of_paths);
  91. // Add an image from the given file path.
  92. // Tries to retrieve the exposure time from the file if
  93. // exposure_time is omitted or the given value is <= 0.0
  94. bool add_from_file_path(const char* file_path, double exposure_time=0.0);
  95. // Read images from a CSV file in this format:
  96. // <path_image_1>,<exposure_time_1>
  97. // <path_image_2>,<exposure_time_2>
  98. // <path_image_3>,<exposure_time_3>
  99. // ...
  100. bool read_from_csv_file(const char* csv_path);
  101. bool get_average_image(Image &output);
  102. bool get_average_image_slow(Image &output);
  103. // Approximate the inverse response function from samples of random pixel locations.
  104. // num_samples: Number of samples
  105. // Returns true if a well-formed inverse response function could be found.
  106. bool get_inverse_response_function(InverseResponseFunction &output, unsigned int num_samples);
  107. // Return a HDR-image given an inverse response function
  108. HdrImage get_hdr_image(const InverseResponseFunction &invRespFunc);
  109. private:
  110. // Sort the images by exposure time
  111. void sort_by_exposure();
  112. // The images
  113. std::vector<Image> m_images;
  114. };
  115. }
  116. #endif // HAADER_ILUCF4Z0