173 lines
12 KiB
C++
173 lines
12 KiB
C++
#ifndef H_Image
|
|
#define H_Image
|
|
|
|
#include <vector>
|
|
#include <Eigen/Dense>
|
|
#include <stb_image.h>
|
|
#include <stb_image_write.h>
|
|
|
|
/// @brief This class encapsulates the raw data of an image.
|
|
/// The Image class has a constructor that takes the width, height, and optionally depth of the image, and dynamically allocates a buffer of size width * height * depth to store the image data. The destructor deallocates the buffer to avoid memory leaks.
|
|
/// The class provides three accessor methods GetWidth(), GetHeight(), and GetDepth() to query the image dimensions.
|
|
/// The GetPixel() method takes the x, y, and z coordinates of the pixel (in row-major order) and returns the corresponding value from the buffer.
|
|
/// The SetPixel() method takes the x, y, and z coordinates of the pixel and a value, and sets the corresponding pixel in the buffer to the given value.
|
|
/// Note that the GetPixel() and SetPixel() methods use the formula z * width * height + y * width + x to compute the index of the pixel in the buffer. This formula assumes row-major order, where the x coordinate varies fastest, followed by the y coordinate, and then the z coordinate. If the image had a different ordering, the formula would need to be adjusted accordingly.
|
|
class Image {
|
|
public:
|
|
/// @brief Interpolation methods.
|
|
enum class InterpMethod {
|
|
NEAREST, ///< Nearest neighbor interpolation.
|
|
BILINEAR, ///< Bilinear interpolation.
|
|
LANCZOS ///< Lanczos filtering interpolation.
|
|
};
|
|
|
|
/// @brief Colormaps LUTs.
|
|
struct Colormap {
|
|
/// @brief MATLAB's parula colormap. 256x3 values : R0G0B0, R1G1B1, ...
|
|
static constexpr unsigned char PARULA[256*3] = {62,38,168 ,62,39,172 ,63,40,175 ,63,41,178 ,64,42,180 ,64,43,183 ,65,44,186 ,65,45,189 ,66,46,191 ,66,47,194 ,67,48,197 ,67,49,200 ,67,50,202 ,68,51,205 ,68,52,208 ,69,53,210 ,69,55,213 ,69,56,215 ,70,57,217 ,70,58,220 ,70,59,222 ,70,61,224 ,71,62,225 ,71,63,227 ,71,65,229 ,71,66,230 ,71,68,232 ,71,69,233 ,71,70,235 ,72,72,236 ,72,73,237 ,72,75,238 ,72,76,240 ,72,78,241 ,72,79,242 ,72,80,243 ,72,82,244 ,72,83,245 ,72,84,246 ,71,86,247 ,71,87,247 ,71,89,248 ,71,90,249 ,71,91,250 ,71,93,250 ,70,94,251 ,70,96,251 ,70,97,252 ,69,98,252 ,69,100,253 ,68,101,253 ,67,103,253 ,67,104,254 ,66,106,254 ,65,107,254 ,64,109,254 ,63,110,255 ,62,112,255 ,60,113,255 ,59,115,255 ,57,116,255 ,56,118,254 ,54,119,254 ,53,121,253 ,51,122,253 ,50,124,252 ,49,125,252 ,48,127,251 ,47,128,250 ,47,130,250 ,46,131,249 ,46,132,248 ,46,134,248 ,46,135,247 ,45,136,246 ,45,138,245 ,45,139,244 ,45,140,243 ,45,142,242 ,44,143,241 ,44,144,240 ,43,145,239 ,42,147,238 ,41,148,237 ,40,149,236 ,39,151,235 ,39,152,234 ,38,153,233 ,38,154,232 ,37,155,232 ,37,156,231 ,36,158,230 ,36,159,229 ,35,160,229 ,35,161,228 ,34,162,228 ,33,163,227 ,32,165,227 ,31,166,226 ,30,167,225 ,29,168,225 ,29,169,224 ,28,170,223 ,27,171,222 ,26,172,221 ,25,173,220 ,23,174,218 ,22,175,217 ,20,176,216 ,18,177,214 ,16,178,213 ,14,179,212 ,11,179,210 ,8,180,209 ,6,181,207 ,4,182,206 ,2,183,204 ,1,183,202 ,0,184,201 ,0,185,199 ,0,186,198 ,1,186,196 ,2,187,194 ,4,187,193 ,6,188,191 ,9,189,189 ,13,189,188 ,16,190,186 ,20,190,184 ,23,191,182 ,26,192,181 ,29,192,179 ,32,193,177 ,35,193,175 ,37,194,174 ,39,194,172 ,41,195,170 ,43,195,168 ,44,196,166 ,46,196,165 ,47,197,163 ,49,197,161 ,50,198,159 ,51,199,157 ,53,199,155 ,54,200,153 ,56,200,150 ,57,201,148 ,59,201,146 ,61,202,144 ,64,202,141 ,66,202,139 ,69,203,137 ,72,203,134 ,75,203,132 ,78,204,129 ,81,204,127 ,84,204,124 ,87,204,122 ,90,204,119 ,94,205,116 ,97,205,114 ,100,205,111 ,103,205,108 ,107,205,105 ,110,205,102 ,114,205,100 ,118,204,97 ,121,204,94 ,125,204,91 ,129,204,89 ,132,204,86 ,136,203,83 ,139,203,81 ,143,203,78 ,147,202,75 ,150,202,72 ,154,201,70 ,157,201,67 ,161,200,64 ,164,200,62 ,167,199,59 ,171,199,57 ,174,198,55 ,178,198,53 ,181,197,51 ,184,196,49 ,187,196,47 ,190,195,45 ,194,195,44 ,197,194,42 ,200,193,41 ,203,193,40 ,206,192,39 ,208,191,39 ,211,191,39 ,214,190,39 ,217,190,40 ,219,189,40 ,222,188,41 ,225,188,42 ,227,188,43 ,230,187,45 ,232,187,46 ,234,186,48 ,236,186,50 ,239,186,53 ,241,186,55 ,243,186,57 ,245,186,59 ,247,186,61 ,249,186,62 ,251,187,62 ,252,188,62 ,254,189,61 ,254,190,60 ,254,192,59 ,254,193,58 ,254,194,57 ,254,196,56 ,254,197,55 ,254,199,53 ,254,200,52 ,254,202,51 ,253,203,50 ,253,205,49 ,253,206,49 ,252,208,48 ,251,210,47 ,251,211,46 ,250,213,46 ,249,214,45 ,249,216,44 ,248,217,43 ,247,219,42 ,247,221,42 ,246,222,41 ,246,224,40 ,245,225,40 ,245,227,39 ,245,229,38 ,245,230,38 ,245,232,37 ,245,233,36 ,245,235,35 ,245,236,34 ,245,238,33 ,246,239,32 ,246,241,31 ,246,242,30 ,247,244,28 ,247,245,27 ,248,247,26 ,248,248,24 ,249,249,22 ,249,251,21};
|
|
};
|
|
|
|
/// @brief Initializes the image with the given width, height, and optionally depth. Warning : the values are uninitialized.
|
|
/// @param width_ Width of the image.
|
|
/// @param height_ Height of the image.
|
|
/// @param depth_ Depth of the image.
|
|
Image(int width_, int height_, int depth_ = 1);
|
|
|
|
/// @brief Copies another image. Performs a deep copy.
|
|
/// @param other The image to copy.
|
|
Image(Image const& other);
|
|
|
|
/// @brief Frees the allocated memory of the image.
|
|
~Image();
|
|
|
|
/// @brief Loads an image from a file.
|
|
/// @param filename Path to the image file.
|
|
Image(std::string const& filename);
|
|
|
|
/// @brief Saves the image to a file.
|
|
/// Supports the following formats : PNG, BMP, TGA, JPG. The format is determined from the file extension.
|
|
/// @param filename Path to save the image to.
|
|
Save(std::string const& filename) const;
|
|
|
|
int GetWidth() const;
|
|
int GetHeight() const;
|
|
int GetDepth() const;
|
|
|
|
/// @brief Fills the image with the given value. All channels are set.
|
|
/// @param value Value to fill the image with.
|
|
Image & Fill(unsigned char value);
|
|
|
|
/// @brief Fills the image with the given rgb value.
|
|
/// @param rgb RGB value to fill the image with.
|
|
Image & Fill(Eigen::Vector3i const& rgb);
|
|
|
|
/// @brief Returns the value of the chosen channel of the given pixel.
|
|
/// @param i Row index.
|
|
/// @param j Column index.
|
|
/// @param c Channel index.
|
|
/// @return The value of the chosen channel of the given pixel.
|
|
unsigned char GetPixelValue(int i, int j, int c = 0) const;
|
|
|
|
/// @brief Sets the value of the chosen channel of the given pixel.
|
|
/// @param i Row index.
|
|
/// @param j Column index.
|
|
/// @param c Channel index.
|
|
/// @param value Value of the chosen channel of the given pixel.
|
|
void SetPixelValue(int i, int j, int c, unsigned char value);
|
|
|
|
/// @brief Returns a mutable reference to the chosen channel of the given pixel.
|
|
/// @param i Row index.
|
|
/// @param j Column index.
|
|
/// @param c Channel index.
|
|
/// @return A mutable reference to the value of the chosen channel of the given pixel.
|
|
unsigned char & PixelValue(int i, int j, int c = 0);
|
|
|
|
/// @brief Returns the given pixel as a 3D-vector containing the RGB values.
|
|
/// @param i Row index.
|
|
/// @param j Column index.
|
|
/// @return Given pixel as a 3D-vector containing the RGB values.
|
|
Eigen::Vector3i GetPixel(int i, int j) const;
|
|
|
|
/// @brief Returns the given pixel as a 3D-vector containing the RGB values.
|
|
/// @param pos 2D vector containing the row and column indices.
|
|
/// @return Given pixel as a 3D-vector containing the RGB values.
|
|
Eigen::Vector3i GetPixel(Eigen::Vector2i const& pos) const;
|
|
|
|
/// @brief Returns the given pixel as a 3D-vector containing the RGB values, using the selected interpolation method.
|
|
/// @param pos 2D vector containing the row and column indices. Floating point values are used.
|
|
/// @param interp_method Interpolation method to use.
|
|
/// @return Interpolated pixel as a 3D-vector containing the RGB values.
|
|
Eigen::Vector3i GetPixelInterp(Eigen::Vector2d const& pos, InterpMethod const& interp_method) const;
|
|
|
|
/// @brief Sets the given pixel to the given RGB values.
|
|
/// @param i Row index.
|
|
/// @param j Column index.
|
|
/// @param rgb 3D-vector containing the RGB values.
|
|
/// @return Reference to the image.
|
|
Image & SetPixel(int i, int j, Eigen::Vector3i const& rgb);
|
|
|
|
/// @brief Sets the given pixel to the given RGB values.
|
|
/// @param pos 2D vector containing the row and column indices.
|
|
/// @param rgb 3D-vector containing the RGB values.
|
|
/// @return Reference to the image.
|
|
Image & SetPixel(Eigen::Vector2i const& pos, Eigen::Vector3i const& rgb);
|
|
|
|
/// @brief Accesses the value at the given index of the raw image data.
|
|
/// @param i Index of the element. Max is (width * height * depth) - 1.
|
|
/// @return The value at the given index of the raw image data.
|
|
unsigned char operator[](int i) const;
|
|
|
|
/// @brief Returns a new image that has been downsampled by a given factor.
|
|
/// @param factor Factor by which the image is downsampled. A factor of 2 will halve the width and height, thus reducing the pixel count by a factor of 2^2 = 4.
|
|
Image Downsampled(int factor) const;
|
|
|
|
/// @brief Returns a new image that represents the grayscale version of the current image.
|
|
/// @return A new image that represents the grayscale version of the current image (average of RGB components).
|
|
Image Grayscale() const;
|
|
|
|
/// @brief Returns a new image that represents the Luma version of the current image, following the REC709 standard.
|
|
/// @return A new image that represents the Luma version of the current image, following the REC709 standard.
|
|
Image LumaREC709() const;
|
|
|
|
/// @brief Performs histrogram normalization on the image (in place). Histogram normalization is a contrast enhancement technique that ensures that the whole range of values is used.
|
|
/// All channels are used to compute the histogram, and all channels are normalized using the same global histogram.
|
|
/// @param downsampling_factor Downsampling factor to use while computing the histogram.
|
|
/// @return A reference to the image.
|
|
Image & HistogramNormalize(int downsampling_factor = 1);
|
|
|
|
/// @brief Returns a histrogram-normalized copy of the image. Histogram normalization is a contrast enhancement technique that ensures that the whole range of values is used.
|
|
/// All channels are used to compute the histogram, and all channels are normalized using the same global histogram.
|
|
/// @param downsampling_factor Downsampling factor to use while computing the histogram.
|
|
/// @return A reference to the image.
|
|
Image HistogramNormalized(int downsampling_factor = 1) const;
|
|
|
|
/// @brief Normalizes the image (in place), so that the minimum value is 0 and the maximum value is 255.
|
|
/// @return A reference to the image.
|
|
Image & Normalize();
|
|
|
|
/// @brief Returns a normalized copy of the image, so that the minimum value is 0 and the maximum value is 255.
|
|
/// @return A normalized copy of the image.
|
|
Image Normalized() const;
|
|
|
|
/// @brief Applies a colormap to the image. After applying the colormap, the image will be 3-channel (RGB). If the image is not single-channel, a unnchanged copy of the image is returned.
|
|
/// @param colormap Array of 256*3 values, representing the RGB values of the colormap. Order is R0, G0, B0, R1, G1, B1, etc.
|
|
/// @return Reference to the image.
|
|
Image Colorized(unsigned char const* colormap) const;
|
|
|
|
/// @brief Computes the histogram of the image.
|
|
/// All channels are used to compute the histogram. If the downscale factor is a multiple of the number of channels, the histogram will be skewed and will only use the first channel.
|
|
/// @param downscale_factor Factor by which the image is downsampled before computing the histogram.
|
|
/// @return The histogram of the image.
|
|
std::vector<uint64_t> ComputeHistogram(int downscale_factor = 1) const;
|
|
|
|
/// @brief Computes the cumulative histogram of the image from its histogram.
|
|
static std::vector<uint64_t> CumulativeHistogram(std::vector<uint64_t> const& histogram);
|
|
|
|
private:
|
|
int width;
|
|
int height;
|
|
int depth;
|
|
unsigned char* data;
|
|
};
|
|
|
|
#endif
|