From 7c9ac7d151f8573f92b5e6c5633a63826b2980be Mon Sep 17 00:00:00 2001 From: "T. van der Zwan" Date: Wed, 21 Aug 2013 15:24:42 +0000 Subject: [PATCH] Added border-ignore to the image-to-leds mapping. Added doxygen comments. --- libsrc/hyperion/ImageProcessor.cpp | 2 +- libsrc/hyperion/ImageToLedsMap.cpp | 32 +++++-- libsrc/hyperion/ImageToLedsMap.h | 136 ++++++++++++++++------------- test/TestImage2LedsMap.cpp | 2 +- 4 files changed, 102 insertions(+), 70 deletions(-) diff --git a/libsrc/hyperion/ImageProcessor.cpp b/libsrc/hyperion/ImageProcessor.cpp index 3fc7b2d8..781fd4be 100644 --- a/libsrc/hyperion/ImageProcessor.cpp +++ b/libsrc/hyperion/ImageProcessor.cpp @@ -30,7 +30,7 @@ void ImageProcessor::setSize(const unsigned width, const unsigned height) delete mImageToLeds; // Construct a new buffer and mapping - mImageToLeds = new ImageToLedsMap(width, height, mLedString.leds()); + mImageToLeds = new ImageToLedsMap(width, height, 0, 0, mLedString.leds()); } std::vector ImageProcessor::process(const RgbImage& image) diff --git a/libsrc/hyperion/ImageToLedsMap.cpp b/libsrc/hyperion/ImageToLedsMap.cpp index e41cd1df..115dd76d 100644 --- a/libsrc/hyperion/ImageToLedsMap.cpp +++ b/libsrc/hyperion/ImageToLedsMap.cpp @@ -7,21 +7,37 @@ using namespace hyperion; -ImageToLedsMap::ImageToLedsMap(const unsigned width, const unsigned height, const std::vector& leds) : +ImageToLedsMap::ImageToLedsMap( + const unsigned width, + const unsigned height, + const unsigned horizontalBorder, + const unsigned verticalBorder, + const std::vector& leds) : _width(width), _height(height), mColorsMap() { + // Sanity check of the size of the borders (and width and height) + assert(width > 2*verticalBorder); + assert(height > 2*horizontalBorder); + // Reserve enough space in the map for the leds mColorsMap.reserve(leds.size()); + const unsigned xOffset = verticalBorder; + const unsigned actualWidth = width - 2 * verticalBorder; + const unsigned yOffset = horizontalBorder; + const unsigned actualHeight = height - 2 * horizontalBorder; + for (const Led& led : leds) { - const unsigned minX_idx = unsigned(width * led.minX_frac); - const unsigned maxX_idx = unsigned(width * led.maxX_frac); - const unsigned minY_idx = unsigned(height * led.minY_frac); - const unsigned maxY_idx = unsigned(height * led.maxY_frac); + // Compute the index boundaries for this led + const unsigned minX_idx = xOffset + unsigned(std::round((actualWidth-1) * led.minX_frac)); + const unsigned maxX_idx = xOffset + unsigned(std::round((actualWidth-1) * led.maxX_frac)); + const unsigned minY_idx = yOffset + unsigned(std::round((actualHeight-1) * led.minY_frac)); + const unsigned maxY_idx = yOffset + unsigned(std::round((actualHeight-1) * led.maxY_frac)); + // Add all the indices in the above defined rectangle to the indices for this led std::vector ledColors; for (unsigned y = minY_idx; y<=maxY_idx && y & colors) const { + // Accumulate the sum of each seperate color channel uint_fast16_t cummRed = 0; uint_fast16_t cummGreen = 0; uint_fast16_t cummBlue = 0; @@ -77,9 +97,11 @@ RgbColor ImageToLedsMap::calcMeanColor(const RgbImage & image, const std::vector cummBlue += color.blue; } + // Compute the average of each color channel const uint8_t avgRed = uint8_t(cummRed/colors.size()); const uint8_t avgGreen = uint8_t(cummGreen/colors.size()); const uint8_t avgBlue = uint8_t(cummBlue/colors.size()); + // Return the computed color return {avgRed, avgGreen, avgBlue}; } diff --git a/libsrc/hyperion/ImageToLedsMap.h b/libsrc/hyperion/ImageToLedsMap.h index 3dbb0e88..3605bf78 100644 --- a/libsrc/hyperion/ImageToLedsMap.h +++ b/libsrc/hyperion/ImageToLedsMap.h @@ -13,71 +13,81 @@ namespace hyperion { -class ImageToLedsMap -{ -public: - - /** - * Constructs an mapping from the colors in the image to each led based on the border - * definition given in the list of leds. The map holds pointers to the given image and its - * lifetime should never exceed that of the given image - * - * @param[in] image The RGB image - * @param[in] leds The list with led specifications - */ - ImageToLedsMap(const unsigned width, const unsigned height, const std::vector & leds); - - unsigned width() const; - - unsigned height() const; - - /** - * Determines the mean-color for each led using the mapping the image given - * at construction. - * - * @return ledColors The vector containing the output - */ - std::vector getMeanLedColor(const RgbImage & image) const; - - /** - * Determines the mean-color for each led using the mapping the image given - * at construction. - * - * @param[out] ledColors The vector containing the output - */ - void getMeanLedColor(const RgbImage & image, std::vector & ledColors) const; - - std::string toString() const + /// + /// The ImageToLedsMap holds a mapping of indices into an image to leds. It can be used to + /// calculate the average (or mean) color per led for a specific region. + /// + class ImageToLedsMap { - std::stringstream sstream; - sstream << "ImageToLedsMap(" << _width << "x" << _height << ") ["; - for (const std::vector imageIndices : mColorsMap) - { - sstream << "{"; - for (unsigned imageIndex : imageIndices) - { - sstream << imageIndex << ";"; - } - sstream << "}"; - } - sstream << "]" << std::endl; + public: - return sstream.str(); - } -private: - const unsigned _width; - const unsigned _height; - std::vector > mColorsMap; + /// + /// Constructs an mapping from the absolute indices in an image to each led based on the border + /// definition given in the list of leds. The map holds absolute indices to any given image, + /// provided that it is row-oriented. + /// The mapping is created purely on size (width and height). The given borders are excluded + /// from indexing. + /// + /// @param[in] width The width of the indexed image + /// @param[in] height The width of the indexed image + /// @param[in] horizontalBorder The size of the horizontal border (0=no border) + /// @param[in] verticalBorder The size of the vertical border (0=no border) + /// @param[in] leds The list with led specifications + /// + ImageToLedsMap( + const unsigned width, + const unsigned height, + const unsigned horizontalBorder, + const unsigned verticalBorder, + const std::vector & leds); - /** - * Finds the 'mean color' of the given list. This is the mean over each color-channel (red, - * green, blue) - * - * @param colors The list with colors - * - * @return The mean of the given list of colors (or black when empty) - */ - RgbColor calcMeanColor(const RgbImage & image, const std::vector & colors) const; -}; + /// + /// Returns the width of the indexed image + /// + /// @return The width of the indexed image [pixels] + /// + unsigned width() const; + + /// + /// Returns the height of the indexed image + /// + /// @return The height of the indexed image [pixels] + /// + unsigned height() const; + + /// + /// Determines the mean-color for each led using the mapping the image given + /// at construction. + /// + /// @return ledColors The vector containing the output + /// + std::vector getMeanLedColor(const RgbImage & image) const; + + /// + /// Determines the mean color for each led using the mapping the image given + /// at construction. + /// + /// @param[out] ledColors The vector containing the output + /// + void getMeanLedColor(const RgbImage & image, std::vector & ledColors) const; + + private: + /// The width of the indexed image + const unsigned _width; + /// The height of the indexed image + const unsigned _height; + /// The absolute indices into the image for each led + std::vector > mColorsMap; + + /// + /// Calculates the 'mean color' of the given list. This is the mean over each color-channel + /// (red, green, blue) + /// + /// @param[in] colors The list with colors + /// + /// @return The mean of the given list of colors (or black when empty) + /// + RgbColor calcMeanColor(const RgbImage & image, const std::vector & colors) const; + }; } // end namespace hyperion diff --git a/test/TestImage2LedsMap.cpp b/test/TestImage2LedsMap.cpp index 752daed0..d358a0de 100644 --- a/test/TestImage2LedsMap.cpp +++ b/test/TestImage2LedsMap.cpp @@ -28,7 +28,7 @@ int main() const RgbColor testColor = {64, 123, 12}; RgbImage image(64, 64, testColor); - ImageToLedsMap map(64, 64, ledString.leds()); + ImageToLedsMap map(64, 64, 0, 0, ledString.leds()); std::vector ledColors(ledString.leds().size()); map.getMeanLedColor(image, ledColors);