bugfix, config enhancement and 3 detection modes

Former-commit-id: edfc3e7ccf7b7d727e73a8563acb521045026d5b
This commit is contained in:
wisc
2016-02-07 13:26:40 +01:00
parent 6b052081f7
commit 2b703de669
11 changed files with 213 additions and 60 deletions

View File

@@ -49,7 +49,7 @@ namespace hyperion
/// Constructs a black-border detector
/// @param[in] blackborderThreshold The threshold which the blackborder detector should use
///
BlackBorderDetector(uint8_t blackborderThreshold);
BlackBorderDetector(double threshold);
///
/// Performs the actual black-border detection on the given image
@@ -58,13 +58,17 @@ namespace hyperion
///
/// @return The detected (or not detected) black border info
///
uint8_t calculateThreshold(double blackborderThreshold);
///
/// default detection mode (3lines 4side detection)
template <typename Pixel_T>
BlackBorder process(const Image<Pixel_T> & image)
{
// test center and 33%, 66% of width/heigth
// 33 and 66 will check left and top
// center ill check right and bottom sids
// center will check right and bottom sids
int width = image.width();
int height = image.height();
int width33percent = width / 3;
@@ -79,9 +83,9 @@ namespace hyperion
int firstNonBlackYPixelIndex = -1;
// find first X pixel of the image
for (int x = 0; x < width; ++x)
for (int x = 0; x < width33percent; ++x)
{
const Pixel_T & color1 = image( (width - x), yCenter); // right side center line check
const Pixel_T & color1 = image( (width - 1 - x), yCenter); // right side center line check
const Pixel_T & color2 = image(x, height33percent);
const Pixel_T & color3 = image(x, height66percent);
if (!isBlack(color1) || !isBlack(color2) || !isBlack(color3))
@@ -92,9 +96,9 @@ namespace hyperion
}
// find first Y pixel of the image
for (int y = 0; y < height; ++y)
for (int y = 0; y < height33percent; ++y)
{
const Pixel_T & color1 = image(xCenter, (height - y)); // bottom center line check
const Pixel_T & color1 = image(xCenter, (height - 1 - y)); // bottom center line check
const Pixel_T & color2 = image(width33percent, y );
const Pixel_T & color3 = image(width66percent, y);
if (!isBlack(color1) || !isBlack(color2) || !isBlack(color3))
@@ -112,6 +116,120 @@ namespace hyperion
return detectedBorder;
}
///
/// classic detection mode (topleft single line mode)
template <typename Pixel_T>
BlackBorder process_classic(const Image<Pixel_T> & image)
{
// only test the topleft third of the image
int width = image.width() /3;
int height = image.height() / 3;
int maxSize = std::max(width, height);
int firstNonBlackXPixelIndex = -1;
int firstNonBlackYPixelIndex = -1;
// find some pixel of the image
for (int i = 0; i < maxSize; ++i)
{
int x = std::min(i, width);
int y = std::min(i, height);
const Pixel_T & color = image(x, y);
if (!isBlack(color))
{
firstNonBlackXPixelIndex = x;
firstNonBlackYPixelIndex = y;
break;
}
}
// expand image to the left
for(; firstNonBlackXPixelIndex > 0; --firstNonBlackXPixelIndex)
{
const Pixel_T & color = image(firstNonBlackXPixelIndex-1, firstNonBlackYPixelIndex);
if (isBlack(color))
{
break;
}
}
// expand image to the top
for(; firstNonBlackYPixelIndex > 0; --firstNonBlackYPixelIndex)
{
const Pixel_T & color = image(firstNonBlackXPixelIndex, firstNonBlackYPixelIndex-1);
if (isBlack(color))
{
break;
}
}
// Construct result
BlackBorder detectedBorder;
detectedBorder.unknown = firstNonBlackXPixelIndex == -1 || firstNonBlackYPixelIndex == -1;
detectedBorder.horizontalSize = firstNonBlackYPixelIndex;
detectedBorder.verticalSize = firstNonBlackXPixelIndex;
return detectedBorder;
}
// osd detection mode (find x then y at detected x to avoid changes by osd overlays)
template <typename Pixel_T>
BlackBorder process_osd(const Image<Pixel_T> & image)
{
// find X position at height33 and height66 we check from the left side, Ycenter will check from right side
// then we try to find a pixel at this X position from top and bottom and right side from top
int width = image.width();
int height = image.height();
int width33percent = width / 3;
int height33percent = height / 3;
// int width66percent = width33percent * 2;
int height66percent = height33percent * 2;
// int xCenter = width / 2;
int yCenter = height / 2;
int firstNonBlackXPixelIndex = -1;
int firstNonBlackYPixelIndex = -1;
// find first X pixel of the image
int x;
for (x = 0; x < width33percent; ++x)
{
const Pixel_T & color1 = image( (width - 1 - x), yCenter); // right side center line check
const Pixel_T & color2 = image(x, height33percent);
const Pixel_T & color3 = image(x, height66percent);
if (!isBlack(color1) || !isBlack(color2) || !isBlack(color3))
{
firstNonBlackXPixelIndex = x;
break;
}
}
// find first Y pixel of the image
for (int y = 0; y < height33percent; ++y)
{
const Pixel_T & color1 = image(x, (height - 1 - y)); // left side bottom check
const Pixel_T & color2 = image(x, y );// left side top check
const Pixel_T & color3 = image( (width - 1 - x), y); // right side top check
if (!isBlack(color1) || !isBlack(color2) || !isBlack(color3))
{
firstNonBlackYPixelIndex = y;
break;
}
}
// Construct result
BlackBorder detectedBorder;
detectedBorder.unknown = firstNonBlackXPixelIndex == -1 || firstNonBlackYPixelIndex == -1;
detectedBorder.horizontalSize = firstNonBlackYPixelIndex;
detectedBorder.verticalSize = firstNonBlackXPixelIndex;
return detectedBorder;
}
private:
///
@@ -131,5 +249,6 @@ namespace hyperion
private:
/// Threshold for the blackborder detector [0 .. 255]
const uint8_t _blackborderThreshold;
};
} // end namespace hyperion

View File

@@ -1,6 +1,8 @@
#pragma once
// Jsoncpp includes
#include <json/json.h>
// Local Hyperion includes
#include "BlackBorderDetector.h"
@@ -23,11 +25,7 @@ namespace hyperion
/// outer pixels is blurred (black and color combined due to image scaling))
/// @param[in] blackborderThreshold The threshold which the blackborder detector should use
///
BlackBorderProcessor(
const unsigned unknownFrameCnt,
const unsigned borderFrameCnt,
const unsigned blurRemoveCnt,
uint8_t blackborderThreshold);
BlackBorderProcessor(const Json::Value &blackborderConfig);
///
/// Return the current (detected) border
@@ -48,7 +46,14 @@ namespace hyperion
bool process(const Image<Pixel_T> & image)
{
// get the border for the single image
BlackBorder imageBorder = _detector.process(image);
BlackBorder imageBorder;
if (_detectionMode == "default") {
imageBorder = _detector.process(image);
} else if (_detectionMode == "classic") {
imageBorder = _detector.process_classic(image);
} else if (_detectionMode == "osd") {
imageBorder = _detector.process_osd(image);
}
// add blur to the border
if (imageBorder.horizontalSize > 0)
{
@@ -80,9 +85,15 @@ namespace hyperion
/// The number of horizontal/vertical borders detected before it becomes the current border
const unsigned _borderSwitchCnt;
// The number of frames that are "ignored" before a new border gets set as _previousDetectedBorder
const unsigned _maxInconsistentCnt;
/// The number of pixels to increase a detected border for removing blury pixels
unsigned _blurRemoveCnt;
/// The border detection mode
const std::string _detectionMode;
/// The blackborder detector
BlackBorderDetector _detector;
@@ -96,5 +107,6 @@ namespace hyperion
unsigned _consistentCnt;
/// The number of frame the previous detected border NOT matched the incomming border
unsigned _inconsistentCnt;
};
} // end namespace hyperion

View File

@@ -106,7 +106,7 @@ private:
/// @param[in] enableBlackBorderDetector Flag indicating if the blacborder detector should be enabled
/// @param[in] blackborderThreshold The threshold which the blackborder detector should use
///
ImageProcessor(const LedString &ledString, bool enableBlackBorderDetector, uint8_t blackborderThreshold);
ImageProcessor(const LedString &ledString, const Json::Value &blackborderConfig);
///
/// Performs black-border detection (if enabled) on the given image

View File

@@ -33,7 +33,7 @@ public:
/// @param[in] enableBlackBorderDetector Flag indicating if the blacborder detector should be enabled
/// @param[in] blackborderThreshold The threshold which the blackborder detector should use
///
void init(const LedString& ledString, bool enableBlackBorderDetector, double blackborderThreshold);
void init(const LedString& ledString, const Json::Value &blackborderConfig);
///
/// Creates a new ImageProcessor. The onwership of the processor is transferred to the caller.
@@ -46,9 +46,6 @@ private:
/// The Led-string specification
LedString _ledString;
/// Flag indicating if the black border detector should be used
bool _enableBlackBorderDetector;
/// Threshold for the blackborder detector [0 .. 255]
uint8_t _blackborderThreshold;
// Reference to the blackborder json configuration values
Json::Value _blackborderConfig;
};