mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Added config-schema of Hyperion as resource.
Added constructor to Hyperion using filename. Added config-filename as commandline parameter for hyperiond. Added implementation of blackborder detector. Added test for blackborder detector.
This commit is contained in:
110
libsrc/hyperion/BlackBorderDetector.cpp
Normal file
110
libsrc/hyperion/BlackBorderDetector.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
#include "BlackBorderDetector.h"
|
||||
|
||||
BlackBorderDetector::BlackBorderDetector()
|
||||
{
|
||||
}
|
||||
|
||||
BlackBorder BlackBorderDetector::process(const RgbImage& image)
|
||||
{
|
||||
int firstNonBlackPixelTop = -1;
|
||||
int firstNonBlackPixelLeft = -1;
|
||||
|
||||
for (unsigned x=0; x<image.width(); ++x)
|
||||
{
|
||||
const RgbColor& color = image(x, 0);
|
||||
if (!isBlack(color))
|
||||
{
|
||||
firstNonBlackPixelTop = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (unsigned y=0; y<image.height(); ++y)
|
||||
{
|
||||
const RgbColor& color = image(0, y);
|
||||
if (!isBlack(color))
|
||||
{
|
||||
firstNonBlackPixelLeft = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BlackBorder detectedBorder;
|
||||
detectedBorder.type = BlackBorder::unknown;
|
||||
|
||||
if (firstNonBlackPixelTop == 0 /*&& firstNonBlackPixelLeft == 0*/)
|
||||
{
|
||||
// No black border
|
||||
// C-?-?-? ...
|
||||
// ? +----
|
||||
// ? |
|
||||
// ? |
|
||||
// :
|
||||
|
||||
detectedBorder.type = BlackBorder::none;
|
||||
detectedBorder.size = -1;
|
||||
}
|
||||
else if (firstNonBlackPixelTop < 0)
|
||||
{
|
||||
if (firstNonBlackPixelLeft < 0 || firstNonBlackPixelLeft > (int)(image.height()/2) )
|
||||
{
|
||||
// We don't know
|
||||
// B-B-B-B ... B-B-B-B
|
||||
// B +---- ... ----- ?
|
||||
// B |
|
||||
// B |
|
||||
// :
|
||||
// B |
|
||||
// B |
|
||||
// B |
|
||||
// B ?
|
||||
|
||||
detectedBorder.type = BlackBorder::unknown;
|
||||
detectedBorder.size = -1;
|
||||
}
|
||||
else //(firstNonBlackPixelLeft > 0 && firstNonBlackPixelLeft < image.height()/2)
|
||||
{
|
||||
// Border at top of screen
|
||||
// B-B-B-B ... B-B-B-B
|
||||
// B +---- ... ----- ?
|
||||
// C |
|
||||
// ? |
|
||||
// :
|
||||
|
||||
detectedBorder.type = BlackBorder::horizontal;
|
||||
detectedBorder.size = firstNonBlackPixelLeft;
|
||||
}
|
||||
}
|
||||
else // (firstNonBlackPixelTop > 0)
|
||||
{
|
||||
if (firstNonBlackPixelTop < int(image.width()/2) && firstNonBlackPixelLeft < 0)
|
||||
{
|
||||
// Border at left of screen
|
||||
// B-B-C-? ...
|
||||
// B +---- ... ----- ?
|
||||
// B |
|
||||
// B |
|
||||
// :
|
||||
// B |
|
||||
// B |
|
||||
// B |
|
||||
// B ?
|
||||
|
||||
detectedBorder.type = BlackBorder::vertical;
|
||||
detectedBorder.size = firstNonBlackPixelTop;
|
||||
}
|
||||
else //(firstNonBlackPixelTop > int(mage.width()/2) || firstNonBlackPixelLeft > 0)
|
||||
{
|
||||
// No black border
|
||||
// B-B-C-? ...
|
||||
// B +----
|
||||
// C |
|
||||
// ? |
|
||||
// :
|
||||
|
||||
detectedBorder.type = BlackBorder::none;
|
||||
detectedBorder.size = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return detectedBorder;
|
||||
}
|
38
libsrc/hyperion/BlackBorderDetector.h
Normal file
38
libsrc/hyperion/BlackBorderDetector.h
Normal file
@@ -0,0 +1,38 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// Utils includes
|
||||
#include <utils/RgbImage.h>
|
||||
|
||||
struct BlackBorder
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
none,
|
||||
horizontal,
|
||||
vertical,
|
||||
unknown
|
||||
};
|
||||
|
||||
Type type;
|
||||
int size;
|
||||
|
||||
};
|
||||
|
||||
class BlackBorderDetector
|
||||
{
|
||||
public:
|
||||
BlackBorderDetector();
|
||||
|
||||
BlackBorder process(const RgbImage& image);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
inline bool isBlack(const RgbColor& color)
|
||||
{
|
||||
return RgbColor::BLACK == color;
|
||||
}
|
||||
|
||||
|
||||
};
|
@@ -18,6 +18,7 @@ SET(Hyperion_HEADERS
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.h
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceTest.h
|
||||
${CURRENT_SOURCE_DIR}/ImageToLedsMap.h
|
||||
${CURRENT_SOURCE_DIR}/BlackBorderDetector.h
|
||||
${CURRENT_SOURCE_DIR}/ColorTransform.h
|
||||
)
|
||||
|
||||
@@ -31,16 +32,24 @@ SET(Hyperion_SOURCES
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp
|
||||
${CURRENT_SOURCE_DIR}/LedDeviceTest.cpp
|
||||
${CURRENT_SOURCE_DIR}/ImageToLedsMap.cpp
|
||||
${CURRENT_SOURCE_DIR}/BlackBorderDetector.cpp
|
||||
${CURRENT_SOURCE_DIR}/ColorTransform.cpp
|
||||
)
|
||||
|
||||
set(Hyperion_RESOURCES
|
||||
${CURRENT_SOURCE_DIR}/resource.qrc
|
||||
)
|
||||
|
||||
QT4_WRAP_CPP(Hyperion_HEADERS_MOC ${Hyperion_QT_HEADERS})
|
||||
|
||||
qt4_add_resources(Hyperion_RESOURCES_RCC ${Hyperion_RESOURCES} OPTIONS "-no-compress")
|
||||
|
||||
add_library(hyperion
|
||||
${Hyperion_HEADERS}
|
||||
${Hyperion_QT_HEADERS}
|
||||
${Hyperion_HEADERS_MOC}
|
||||
${Hyperion_SOURCES}
|
||||
${Hyperion_RESOURCES_RCC}
|
||||
)
|
||||
|
||||
target_link_libraries(hyperion
|
||||
|
@@ -1,8 +1,7 @@
|
||||
|
||||
// Syslog include
|
||||
#include <syslog.h>
|
||||
|
||||
// QT includes
|
||||
#include <QDateTime>
|
||||
#include <QResource>
|
||||
|
||||
// JsonSchema include
|
||||
#include <utils/jsonschema/JsonFactory.h>
|
||||
@@ -75,6 +74,33 @@ LedString Hyperion::createLedString(const Json::Value& ledsConfig)
|
||||
return ledString;
|
||||
}
|
||||
|
||||
Json::Value Hyperion::loadConfig(const std::string& configFile)
|
||||
{
|
||||
// read the json schema from the resource
|
||||
QResource schemaData(":/hyperion.schema.json");
|
||||
assert(schemaData.isValid());
|
||||
|
||||
Json::Reader jsonReader;
|
||||
Json::Value schemaJson;
|
||||
if (!jsonReader.parse(reinterpret_cast<const char *>(schemaData.data()), reinterpret_cast<const char *>(schemaData.data()) + schemaData.size(), schemaJson, false))
|
||||
{
|
||||
throw std::runtime_error("Schema error: " + jsonReader.getFormattedErrorMessages()) ;
|
||||
}
|
||||
JsonSchemaChecker schemaChecker;
|
||||
schemaChecker.setSchema(schemaJson);
|
||||
|
||||
const Json::Value jsonConfig = JsonFactory::readJson(configFile);
|
||||
schemaChecker.validate(jsonConfig);
|
||||
|
||||
return jsonConfig;
|
||||
}
|
||||
|
||||
Hyperion::Hyperion(const std::string& configFile) :
|
||||
Hyperion(loadConfig(configFile))
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
Hyperion::Hyperion(const Json::Value &jsonConfig) :
|
||||
mLedString(createLedString(jsonConfig["leds"])),
|
||||
mRedTransform( createColorTransform(jsonConfig["color"]["red"])),
|
||||
|
142
libsrc/hyperion/hyperion.schema.json
Normal file
142
libsrc/hyperion/hyperion.schema.json
Normal file
@@ -0,0 +1,142 @@
|
||||
{
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties":{
|
||||
"device": {
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties":{
|
||||
"name": {
|
||||
"type":"string",
|
||||
"required":true
|
||||
},
|
||||
"type": {
|
||||
"type":"string",
|
||||
"required":true
|
||||
},
|
||||
"output": {
|
||||
"type":"string",
|
||||
"required":true
|
||||
},
|
||||
"interval": {
|
||||
"type":"integer",
|
||||
"required":true
|
||||
},
|
||||
"rate": {
|
||||
"type":"integer",
|
||||
"required":true
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"color": {
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties": {
|
||||
"red": {
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties":{
|
||||
"gamma": {
|
||||
"type":"number",
|
||||
"required":true
|
||||
},
|
||||
"adjust": {
|
||||
"type":"number",
|
||||
"required":true
|
||||
},
|
||||
"blacklevel": {
|
||||
"type":"number",
|
||||
"required":true
|
||||
},
|
||||
"whitelevel": {
|
||||
"type":"number",
|
||||
"required":true
|
||||
},
|
||||
"threshold": {
|
||||
"type":"number",
|
||||
"required":true
|
||||
}
|
||||
}
|
||||
},
|
||||
"green": {
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties":{
|
||||
"gamma": {
|
||||
"type":"number",
|
||||
"required":true
|
||||
},
|
||||
"adjust": {
|
||||
"type":"number",
|
||||
"required":true
|
||||
},
|
||||
"blacklevel": {
|
||||
"type":"number",
|
||||
"required":true
|
||||
}
|
||||
}
|
||||
},
|
||||
"blue": {
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties":{
|
||||
"gamma": {
|
||||
"type":"number",
|
||||
"required":true
|
||||
},
|
||||
"adjust": {
|
||||
"type":"number",
|
||||
"required":true
|
||||
},
|
||||
"blacklevel": {
|
||||
"type":"number",
|
||||
"required":true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"leds": {
|
||||
"type":"array",
|
||||
"required":true,
|
||||
"items": {
|
||||
"type":"object",
|
||||
"properties": {
|
||||
"index": {
|
||||
"type":"integer",
|
||||
"required":true
|
||||
},
|
||||
"hscan": {
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties": {
|
||||
"minimum": {
|
||||
"type":"number",
|
||||
"required":true
|
||||
},
|
||||
"maximum": {
|
||||
"type":"number",
|
||||
"required":true
|
||||
}
|
||||
}
|
||||
},
|
||||
"vscan": {
|
||||
"type":"object",
|
||||
"required":true,
|
||||
"properties": {
|
||||
"minimum": {
|
||||
"type":"number",
|
||||
"required":true
|
||||
},
|
||||
"maximum": {
|
||||
"type":"number",
|
||||
"required":true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
5
libsrc/hyperion/resource.qrc
Normal file
5
libsrc/hyperion/resource.qrc
Normal file
@@ -0,0 +1,5 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>hyperion.schema.json</file>
|
||||
</qresource>
|
||||
</RCC>
|
Reference in New Issue
Block a user