Added 'rainbow' boot sequence

Moved color transform to utils lib
This commit is contained in:
T. van der Zwan 2013-08-23 16:24:10 +00:00
parent 6ee94409dc
commit 3d02fecc7a
20 changed files with 218 additions and 78 deletions

View File

@ -0,0 +1,32 @@
#pragma once
// QT includes
#include <QTimer>
// Hyperion includes
#include <hyperion/Hyperion.h>
class RainbowBootSequence : public QObject
{
Q_OBJECT
public:
RainbowBootSequence(Hyperion * hyperion);
void start();
private slots:
void update();
private:
QTimer _timer;
Hyperion * _hyperion;
int _priority;
std::vector<RgbColor> _ledColors;
int _iterationCounter;
};

View File

@ -16,10 +16,8 @@
#include <hyperion/PriorityMuxer.h>
// Forward class declaration
namespace hyperion {
class HsvTransform;
class ColorTransform;
}
class HsvTransform;
class ColorTransform;
class Hyperion : public QObject
{
@ -74,10 +72,10 @@ private:
PriorityMuxer _muxer;
hyperion::HsvTransform * _hsvTransform;
hyperion::ColorTransform * _redTransform;
hyperion::ColorTransform * _greenTransform;
hyperion::ColorTransform * _blueTransform;
HsvTransform * _hsvTransform;
ColorTransform * _redTransform;
ColorTransform * _greenTransform;
ColorTransform * _blueTransform;
LedDevice* _device;

View File

@ -3,9 +3,6 @@
// STL includes
#include <cstdint>
namespace hyperion
{
/// Transform for a single color byte value
///
/// Transforms are applied in the following order:
@ -51,5 +48,3 @@ private:
uint8_t _mapping[256];
};
} // end namespace hyperion

View File

@ -0,0 +1,30 @@
#pragma once
// STL includes
#include <cstdint>
class HsvTransform
{
public:
HsvTransform();
HsvTransform(double saturationGain, double valueGain);
~HsvTransform();
void setSaturationGain(double saturationGain);
double getSaturationGain() const;
void setValueGain(double valueGain);
double getValueGain() const;
void transform(uint8_t & red, uint8_t & green, uint8_t & blue) const;
/// integer version of the conversion are faster, but a little less accurate
/// all values are unsigned 8 bit values and scaled between 0 and 255 except
/// for the hue which is a 16 bit number and scaled between 0 and 360
static void rgb2hsv(uint8_t red, uint8_t green, uint8_t blue, uint16_t & hue, uint8_t & saturation, uint8_t & value);
static void hsv2rgb(uint16_t hue, uint8_t saturation, uint8_t value, uint8_t & red, uint8_t & green, uint8_t & blue);
private:
double _saturationGain;
double _valueGain;
};

View File

@ -3,7 +3,8 @@
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc)
add_subdirectory(hyperion)
add_subdirectory(bootsequence)
add_subdirectory(dispmanx-grabber)
add_subdirectory(hyperion)
add_subdirectory(jsonserver)
add_subdirectory(utils)

View File

@ -0,0 +1,29 @@
# Define the current source locations
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/bootsequence)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/bootsequence)
# Group the headers that go through the MOC compiler
SET(BootsequenceQT_HEADERS
${CURRENT_HEADER_DIR}/RainbowBootSequence.h
)
SET(BootsequenceHEADERS
)
SET(BootsequenceSOURCES
${CURRENT_SOURCE_DIR}/RainbowBootSequence.cpp
)
QT4_WRAP_CPP(BootsequenceHEADERS_MOC ${BootsequenceQT_HEADERS})
add_library(bootsequence
${BootsequenceHEADERS}
${BootsequenceQT_HEADERS}
${BootsequenceHEADERS_MOC}
${BootsequenceSOURCES}
)
target_link_libraries(bootsequence
hyperion
${QT_LIBRARIES})

View File

@ -0,0 +1,54 @@
#include <utils/HsvTransform.h>
#include <bootsequence/RainbowBootSequence.h>
RainbowBootSequence::RainbowBootSequence(Hyperion * hyperion) :
_timer(),
_hyperion(hyperion),
_priority(0),
_ledColors(hyperion->getLedCount()),
_iterationCounter(hyperion->getLedCount())
{
for (unsigned iLed=0; iLed<_hyperion->getLedCount(); ++iLed)
{
RgbColor& color = _ledColors[iLed];
HsvTransform::hsv2rgb(iLed*360/_hyperion->getLedCount(), 255, 255, color.red, color.green, color.blue);
}
unsigned sequenceLength_ms = 3000;
_timer.setInterval(sequenceLength_ms/_hyperion->getLedCount());
_timer.setSingleShot(false);
QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(update()));
}
void RainbowBootSequence::start()
{
_timer.start();
}
void RainbowBootSequence::update()
{
if (_iterationCounter == 0)
{
_timer.stop();
_hyperion->clear(_priority);
}
else
{
// Rotate the colors left
const RgbColor headColor = _ledColors.front();
for (unsigned i=1; i<_ledColors.size(); ++i)
{
_ledColors[i-1] = _ledColors[i];
}
_ledColors.back() = headColor;
// Write the colors to hyperion
_hyperion->setColors(_priority, _ledColors, -1);
// Decrease the loop count
--_iterationCounter;
}
}

View File

@ -27,6 +27,28 @@ namespace hyperion
/// The size of detected border (negative if not applicable)
int size;
///
/// Compares this BlackBorder to the given other BlackBorder
///
/// @param[in] other The other BlackBorder
///
/// @return True if this is the same border as other
///
inline bool operator== (const BlackBorder& other) const
{
switch (type)
{
case none:
case unknown:
return other.type == type;
case horizontal:
case vertical:
return type == other.type && size == other.size;
}
return false;
}
};
///

View File

@ -13,7 +13,7 @@ BlackBorderProcessor::BlackBorderProcessor(
_blurRemoveCnt(blurRemoveCnt),
_detector(),
_currentBorder({BlackBorder::unknown, 0}),
_lastDetectedBorder({BlackBorder::unknown, 0}),
_previousDetectedBorder({BlackBorder::unknown, 0}),
_consistentCnt(0)
{
}
@ -32,35 +32,50 @@ bool BlackBorderProcessor::process(const RgbImage& image)
{
const BlackBorder imageBorder = _detector.process(image);
if (imageBorder.type == _lastDetectedBorder.type && imageBorder.size == _lastDetectedBorder.size)
if (imageBorder == _previousDetectedBorder)
{
++_consistentCnt;
}
else
{
_lastDetectedBorder = imageBorder;
_consistentCnt = 0;
_previousDetectedBorder = imageBorder;
_consistentCnt = 0;
}
if (_currentBorder == imageBorder)
{
// No change required
return false;
}
bool borderChanged = false;
switch (_lastDetectedBorder.type)
switch (imageBorder.type)
{
case BlackBorder::none:
borderChanged = (_currentBorder.type != BlackBorder::none);
_currentBorder = _lastDetectedBorder;
if (_consistentCnt == 0)
{
_currentBorder = imageBorder;
borderChanged = true;
}
break;
case BlackBorder::horizontal:
case BlackBorder::vertical:
if (_consistentCnt == _borderSwitchCnt)
if (_currentBorder.type == BlackBorder::vertical || imageBorder.size < _currentBorder.size || _consistentCnt == _borderSwitchCnt)
{
_currentBorder = _lastDetectedBorder;
_currentBorder = imageBorder;
borderChanged = true;
}
break;
case BlackBorder::vertical:
if (_currentBorder.type == BlackBorder::horizontal || imageBorder.size < _currentBorder.size || _consistentCnt == _borderSwitchCnt)
{
_currentBorder = imageBorder;
borderChanged = true;
}
break;
case BlackBorder::unknown:
if (_consistentCnt == _unknownSwitchCnt)
{
_currentBorder = _lastDetectedBorder;
_currentBorder = imageBorder;
borderChanged = true;
}
break;

View File

@ -30,7 +30,7 @@ namespace hyperion
BlackBorder _currentBorder;
BlackBorder _lastDetectedBorder;
BlackBorder _previousDetectedBorder;
unsigned _consistentCnt;
};

View File

@ -17,8 +17,6 @@ SET(Hyperion_HEADERS
${CURRENT_SOURCE_DIR}/BlackBorderDetector.h
${CURRENT_SOURCE_DIR}/BlackBorderProcessor.h
${CURRENT_SOURCE_DIR}/ColorTransform.h
${CURRENT_SOURCE_DIR}/HsvTransform.h
${CURRENT_SOURCE_DIR}/ImageToLedsMap.h
${CURRENT_SOURCE_DIR}/LedDeviceTest.h
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.h
@ -33,8 +31,6 @@ SET(Hyperion_SOURCES
${CURRENT_SOURCE_DIR}/BlackBorderDetector.cpp
${CURRENT_SOURCE_DIR}/BlackBorderProcessor.cpp
${CURRENT_SOURCE_DIR}/ColorTransform.cpp
${CURRENT_SOURCE_DIR}/HsvTransform.cpp
${CURRENT_SOURCE_DIR}/ImageToLedsMap.cpp
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp
${CURRENT_SOURCE_DIR}/LedDeviceTest.cpp

View File

@ -1,35 +0,0 @@
#pragma once
#include <cstdint>
namespace hyperion
{
class HsvTransform
{
public:
HsvTransform();
HsvTransform(double saturationGain, double valueGain);
~HsvTransform();
void setSaturationGain(double saturationGain);
double getSaturationGain() const;
void setValueGain(double valueGain);
double getValueGain() const;
void transform(uint8_t & red, uint8_t & green, uint8_t & blue) const;
private:
/// integer version of the conversion are faster, but a little less accurate
/// all values are unsigned 8 bit values and scaled between 0 and 255 except
/// for the hue which is a 16 bit number and scaled between 0 and 360
static void rgb2hsv(uint8_t red, uint8_t green, uint8_t blue, uint16_t & hue, uint8_t & saturation, uint8_t & value);
static void hsv2rgb(uint16_t hue, uint8_t saturation, uint8_t value, uint8_t & red, uint8_t & green, uint8_t & blue);
private:
double _saturationGain;
double _valueGain;
};
} // namespace hyperion

View File

@ -13,10 +13,9 @@
#include "LedDeviceWs2801.h"
#include "LedDeviceTest.h"
#include "ColorTransform.h"
#include "HsvTransform.h"
using namespace hyperion;
#include <utils/ColorTransform.h>
#include <utils/HsvTransform.h>
LedDevice* constructDevice(const Json::Value& deviceConfig)
{

View File

@ -2,9 +2,10 @@
// Hyperion includes
#include <hyperion/ImageProcessor.h>
#include <utils/ColorTransform.h>
// Local-Hyperion includes
#include "BlackBorderProcessor.h"
#include "ColorTransform.h"
#include "ImageToLedsMap.h"
using namespace hyperion;

View File

@ -6,9 +6,13 @@ SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/utils)
add_library(hyperion-utils
${CURRENT_HEADER_DIR}/RgbColor.h
${CURRENT_HEADER_DIR}/RgbImage.h
${CURRENT_HEADER_DIR}/ColorTransform.h
${CURRENT_HEADER_DIR}/HsvTransform.h
${CURRENT_SOURCE_DIR}/RgbColor.cpp
${CURRENT_SOURCE_DIR}/RgbImage.cpp
${CURRENT_SOURCE_DIR}/ColorTransform.cpp
${CURRENT_SOURCE_DIR}/HsvTransform.cpp
${CURRENT_HEADER_DIR}/jsonschema/JsonFactory.h
${CURRENT_HEADER_DIR}/jsonschema/JsonSchemaChecker.h

View File

@ -1,9 +1,7 @@
// STL includes
#include <cmath>
#include "ColorTransform.h"
using namespace hyperion;
#include <utils/ColorTransform.h>
ColorTransform::ColorTransform() :
_threshold(0),

View File

@ -1,6 +1,4 @@
#include "HsvTransform.h"
using namespace hyperion;
#include <utils/HsvTransform.h>
HsvTransform::HsvTransform() :
_saturationGain(1.0),

View File

@ -3,6 +3,7 @@ add_executable(hyperiond
hyperiond.cpp)
target_link_libraries(hyperiond
bootsequence
hyperion
dispmanx-grabber
jsonserver)

View File

@ -10,6 +10,7 @@
// Hyperion includes
#include <hyperion/Hyperion.h>
#include <bootsequence/RainbowBootSequence.h>
// Dispmanx grabber includes
#include <dispmanx-grabber/DispmanxWrapper.h>
@ -44,6 +45,9 @@ int main(int argc, char** argv)
Hyperion hyperion(configFile);
std::cout << "Hyperion created and initialised" << std::endl;
RainbowBootSequence bootSequence(&hyperion);
bootSequence.start();
DispmanxWrapper dispmanx(64, 64, 10, &hyperion);
dispmanx.start();
std::cout << "Frame grabber created and started" << std::endl;

View File

@ -2,9 +2,7 @@
#include <iostream>
#include <cmath>
#include <../../libsrc/hyperion/ColorTransform.h>
using namespace hyperion;
#include <utils/ColorTransform.h>
int main()
{