adjustable image2led mode for grabbers (#341)

* implement most points for a adjustable image2leds mapping

* implement new adjustable led mapping type
This commit is contained in:
redPanther
2016-12-19 23:59:50 +01:00
committed by GitHub
parent 53924c4fca
commit c5e0299c55
21 changed files with 258 additions and 47 deletions

View File

@@ -6,6 +6,7 @@ SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/hyperion)
# Group the headers that go through the MOC compiler
SET(Hyperion_QT_HEADERS
${CURRENT_HEADER_DIR}/Hyperion.h
${CURRENT_HEADER_DIR}/ImageProcessor.h
${CURRENT_SOURCE_DIR}/LinearColorSmoothing.h
${CURRENT_HEADER_DIR}/GrabberWrapper.h
@@ -13,7 +14,6 @@ SET(Hyperion_QT_HEADERS
)
SET(Hyperion_HEADERS
${CURRENT_HEADER_DIR}/ImageProcessor.h
${CURRENT_HEADER_DIR}/ImageProcessorFactory.h
${CURRENT_HEADER_DIR}/ImageToLedsMap.h
${CURRENT_HEADER_DIR}/LedString.h

View File

@@ -20,6 +20,7 @@ GrabberWrapper::GrabberWrapper(std::string grabberName, const int priority, hype
_hyperion->getComponentRegister().componentStateChanged(hyperion::COMP_BLACKBORDER, _processor->blackBorderDetectorEnabled());
qRegisterMetaType<hyperion::Components>("hyperion::Components");
connect(_hyperion, SIGNAL(imageToLedsMappingChanged(int)), _processor, SLOT(setLedMappingType(int)));
connect(_hyperion, SIGNAL(componentStateChanged(hyperion::Components,bool)), this, SLOT(componentStateChanged(hyperion::Components,bool)));
connect(&_timer, SIGNAL(timeout()), this, SLOT(action()));
}
@@ -120,4 +121,3 @@ void GrabberWrapper::setColors(const std::vector<ColorRgb> &ledColors, const int
{
_hyperion->setColors(_priority, ledColors, timeout_ms, true, _grabberComponentId);
}

View File

@@ -17,6 +17,7 @@
// hyperion include
#include <hyperion/Hyperion.h>
#include <hyperion/ImageProcessorFactory.h>
#include <hyperion/ImageProcessor.h>
#include <hyperion/ColorTransform.h>
#include <hyperion/ColorAdjustment.h>
@@ -561,7 +562,8 @@ Hyperion::Hyperion(const QJsonObject &qjsonConfig, const QString configFile)
// initialize the image processor factory
ImageProcessorFactory::getInstance().init(
_ledString,
qjsonConfig["blackborderdetector"].toObject()
qjsonConfig["blackborderdetector"].toObject(),
ImageProcessor::mappingTypeToInt(color["imageToLedMappingType"].toString())
);
getComponentRegister().componentStateChanged(hyperion::COMP_FORWARDER, _messageForwarder->forwardingEnabled());
@@ -852,6 +854,11 @@ int Hyperion::setEffect(const QString &effectName, const QJsonObject &args, int
return _effectEngine->runEffect(effectName, args, priority, timeout, pythonScript);
}
void Hyperion::setLedMappingType(int mappingType)
{
emit imageToLedsMappingChanged(mappingType);
}
void Hyperion::update()
{
// Update the muxer, cleaning obsolete priorities

View File

@@ -1,5 +1,6 @@
// Hyperion includes
#include <hyperion/Hyperion.h>
#include <hyperion/ImageProcessor.h>
#include <hyperion/ImageToLedsMap.h>
@@ -8,13 +9,16 @@
using namespace hyperion;
//ImageProcessor::ImageProcessor(const LedString& ledString, bool enableBlackBorderDetector, uint8_t blackborderThreshold) :
ImageProcessor::ImageProcessor(const LedString& ledString, const QJsonObject & blackborderConfig) :
_ledString(ledString),
_borderProcessor(new BlackBorderProcessor(blackborderConfig) ),
_imageToLeds(nullptr)
ImageProcessor::ImageProcessor(const LedString& ledString, const QJsonObject & blackborderConfig)
: QObject()
, _log(Logger::getInstance("BLACKBORDER"))
, _ledString(ledString)
, _borderProcessor(new BlackBorderProcessor(blackborderConfig) )
, _imageToLeds(nullptr)
, _mappingType(0)
{
// empty
// this is when we want to change the mapping for all input sources
// connect(Hyperion::getInstance(), SIGNAL(imageToLedsMappingChanged(int)), this, SLOT(setLedMappingType(int)));
}
ImageProcessor::~ImageProcessor()
@@ -53,6 +57,25 @@ bool ImageProcessor::blackBorderDetectorEnabled()
return _borderProcessor->enabled();
}
void ImageProcessor::setLedMappingType(int mapType)
{
Debug(_log, "set led mapping to type %d", mapType);
_mappingType = mapType;
}
int ImageProcessor::ledMappingType()
{
return _mappingType;
}
int ImageProcessor::mappingTypeToInt(QString mappingType)
{
if (mappingType == "unicolor_mean" )
return 1;
return 0;
}
bool ImageProcessor::getScanParameters(size_t led, double &hscanBegin, double &hscanEnd, double &vscanBegin, double &vscanEnd) const
{
if (led < _ledString.leds().size())

View File

@@ -9,13 +9,17 @@ ImageProcessorFactory& ImageProcessorFactory::getInstance()
return instance;
}
void ImageProcessorFactory::init(const LedString& ledString, const QJsonObject & blackborderConfig)
void ImageProcessorFactory::init(const LedString& ledString, const QJsonObject & blackborderConfig, int mappingType)
{
_ledString = ledString;
_blackborderConfig = blackborderConfig;
_mappingType = mappingType;
}
ImageProcessor* ImageProcessorFactory::newImageProcessor() const
{
return new ImageProcessor(_ledString, _blackborderConfig);
ImageProcessor* ip = new ImageProcessor(_ledString, _blackborderConfig);
ip->setLedMappingType(_mappingType);
return ip;
}

View File

@@ -18,26 +18,26 @@ ImageToLedsMap::ImageToLedsMap(
, _height(height)
, _horizontalBorder(horizontalBorder)
, _verticalBorder(verticalBorder)
, mColorsMap()
, _colorsMap()
{
// Sanity check of the size of the borders (and width and height)
assert(width > 2*verticalBorder);
assert(height > 2*horizontalBorder);
assert(_width > 2*_verticalBorder);
assert(_height > 2*_horizontalBorder);
// Reserve enough space in the map for the leds
mColorsMap.reserve(leds.size());
_colorsMap.reserve(leds.size());
const unsigned xOffset = verticalBorder;
const unsigned actualWidth = width - 2 * verticalBorder;
const unsigned yOffset = horizontalBorder;
const unsigned actualHeight = height - 2 * horizontalBorder;
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)
{
// skip leds without area
if ((led.maxX_frac-led.minX_frac) < 1e-6 || (led.maxY_frac-led.minY_frac) < 1e-6)
{
mColorsMap.emplace_back();
_colorsMap.emplace_back();
continue;
}
@@ -70,7 +70,7 @@ ImageToLedsMap::ImageToLedsMap(
}
// Add the constructed vector to the map
mColorsMap.push_back(ledColors);
_colorsMap.push_back(ledColors);
}
}

View File

@@ -51,6 +51,7 @@
"type" : "string",
"title" : "edt_dev_general_colorOrder_title",
"enum" : ["rgb", "bgr", "rbg", "brg", "gbr", "grb"],
"default" : "rgb",
"propertyOrder" : 3
},
"rewriteTime": {
@@ -70,26 +71,33 @@
"type":"object",
"title" : "edt_conf_color_heading_title",
"required" : true,
"defaultProperties": ["channelAdjustment_enable","channelAdjustment","transform_enable","transform"],
"defaultProperties": ["imageToLedMappingType","channelAdjustment_enable","channelAdjustment","transform_enable","transform"],
"properties":
{
"imageToLedMappingType" :
{
"type" : "string",
"enum" : ["multicolor_mean", "unicolor_mean"],
"default" : "multicolor_mean",
"propertyOrder" : 1
},
"channelAdjustment_enable" :
{
"type" : "boolean",
"default" : true,
"propertyOrder" : 1
"propertyOrder" : 2
},
"channelAdjustment_v4l_only" :
{
"type" : "boolean",
"default" : false,
"propertyOrder" : 2
"propertyOrder" : 3
},
"channelAdjustment" :
{
"type" : "array",
"required" : true,
"propertyOrder" : 3,
"propertyOrder" : 4,
"items" :
{
"type" : "object",
@@ -204,19 +212,19 @@
{
"type" : "boolean",
"default" : true,
"propertyOrder" : 4
"propertyOrder" : 5
},
"transform_v4l_only" :
{
"type" : "boolean",
"default" : false,
"propertyOrder" : 5
"propertyOrder" : 6
},
"transform" :
{
"type" : "array",
"required" : true,
"propertyOrder" : 6,
"propertyOrder" : 7,
"items" :
{
"type" : "object",

View File

@@ -319,6 +319,8 @@ void JsonClientConnection::handleMessage(const QString& messageString)
handleLedColorsCommand(message, command, tan);
else if (command == "logging")
handleLoggingCommand(message, command, tan);
else if (command == "processing")
handleProcessingCommand(message, command, tan);
else
handleNotImplemented();
}
@@ -1272,6 +1274,13 @@ void JsonClientConnection::handleLoggingCommand(const QJsonObject& message, cons
sendSuccessReply(command+"-"+subcommand,tan);
}
void JsonClientConnection::handleProcessingCommand(const QJsonObject& message, const QString &command, const int tan)
{
_hyperion->setLedMappingType(ImageProcessor::mappingTypeToInt( message["mappingType"].toString("multicolor_mean")) );
sendSuccessReply(command, tan);
}
void JsonClientConnection::incommingLogMessage(Logger::T_LOG_MESSAGE msg)
{
QJsonObject result, message;

View File

@@ -265,6 +265,12 @@ private:
///
void handleLoggingCommand(const QJsonObject & message, const QString &command, const int tan);
/// Handle an incoming JSON Proccessing message
///
/// @param message the incoming message
///
void handleProcessingCommand(const QJsonObject & message, const QString &command, const int tan);
///
/// Handle an incoming JSON message of unknown type
///

View File

@@ -16,5 +16,6 @@
<file alias="schema-componentstate">schema/schema-componentstate.json</file>
<file alias="schema-ledcolors">schema/schema-ledcolors.json</file>
<file alias="schema-logging">schema/schema-logging.json</file>
<file alias="schema-processing">schema/schema-processing.json</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,19 @@
{
"type":"object",
"required":true,
"properties":{
"command": {
"type" : "string",
"required" : true,
"enum" : ["processing"]
},
"tan" : {
"type" : "integer"
},
"mappingType": {
"type" : "string",
"enum" : ["multicolor_mean", "unicolor_mean"]
}
},
"additionalProperties": false
}

View File

@@ -5,7 +5,7 @@
"command": {
"type" : "string",
"required" : true,
"enum" : ["color", "image", "effect", "create-effect", "delete-effect", "serverinfo", "clear", "clearall", "transform", "adjustment", "sourceselect", "config", "componentstate", "ledcolors", "logging"]
"enum" : ["color", "image", "effect", "create-effect", "delete-effect", "serverinfo", "clear", "clearall", "transform", "adjustment", "sourceselect", "config", "componentstate", "ledcolors", "logging", "processing"]
}
}
}