mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Moved black border detection code to seperate library
Former-commit-id: 590029949b79689ea05409149677e51b748cb64f
This commit is contained in:
136
include/blackborder/BlackBorderDetector.h
Normal file
136
include/blackborder/BlackBorderDetector.h
Normal file
@@ -0,0 +1,136 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// Utils includes
|
||||
#include <utils/Image.h>
|
||||
|
||||
namespace hyperion
|
||||
{
|
||||
///
|
||||
/// Result structure of the detected blackborder.
|
||||
///
|
||||
struct BlackBorder
|
||||
{
|
||||
/// Falg indicating if the border is unknown
|
||||
bool unknown;
|
||||
|
||||
/// The size of the detected horizontal border
|
||||
int horizontalSize;
|
||||
|
||||
/// The size of the detected vertical border
|
||||
int verticalSize;
|
||||
|
||||
///
|
||||
/// 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
|
||||
{
|
||||
if (unknown)
|
||||
{
|
||||
return other.unknown;
|
||||
}
|
||||
|
||||
return other.unknown==false && horizontalSize==other.horizontalSize && verticalSize==other.verticalSize;
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// The BlackBorderDetector performs detection of black-borders on a single image.
|
||||
/// The detector will search for the upper left corner of the picture in the frame.
|
||||
/// Based on detected black pixels it will give an estimate of the black-border.
|
||||
///
|
||||
class BlackBorderDetector
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs a black-border detector
|
||||
/// @param[in] blackborderThreshold The threshold which the blackborder detector should use
|
||||
///
|
||||
BlackBorderDetector(uint8_t blackborderThreshold);
|
||||
|
||||
///
|
||||
/// Performs the actual black-border detection on the given image
|
||||
///
|
||||
/// @param[in] image The image on which detection is performed
|
||||
///
|
||||
/// @return The detected (or not detected) black border info
|
||||
///
|
||||
template <typename Pixel_T>
|
||||
BlackBorder process(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;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
///
|
||||
/// Checks if a given color is considered black and therefor could be part of the border.
|
||||
///
|
||||
/// @param[in] color The color to check
|
||||
///
|
||||
/// @return True if the color is considered black else false
|
||||
///
|
||||
template <typename Pixel_T>
|
||||
inline bool isBlack(const Pixel_T & color)
|
||||
{
|
||||
// Return the simple compare of the color against black
|
||||
return color.red < _blackborderThreshold && color.green < _blackborderThreshold && color.green < _blackborderThreshold;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Threshold for the blackborder detector [0 .. 255]
|
||||
const uint8_t _blackborderThreshold;
|
||||
};
|
||||
} // end namespace hyperion
|
98
include/blackborder/BlackBorderProcessor.h
Normal file
98
include/blackborder/BlackBorderProcessor.h
Normal file
@@ -0,0 +1,98 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
// Local Hyperion includes
|
||||
#include "BlackBorderDetector.h"
|
||||
|
||||
namespace hyperion
|
||||
{
|
||||
///
|
||||
/// The BlackBorder processor is a wrapper around the black-border detector for keeping track of
|
||||
/// detected borders and count of the type and size of detected borders.
|
||||
///
|
||||
class BlackBorderProcessor
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructor for the BlackBorderProcessor
|
||||
/// @param unknownFrameCnt The number of frames(images) that need to contain an unknown
|
||||
/// border before the current border is set to unknown
|
||||
/// @param borderFrameCnt The number of frames(images) that need to contain a vertical or
|
||||
/// horizontal border becomes the current border
|
||||
/// @param blurRemoveCnt The size to add to a horizontal or vertical border (because the
|
||||
/// 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);
|
||||
|
||||
///
|
||||
/// Return the current (detected) border
|
||||
/// @return The current border
|
||||
///
|
||||
BlackBorder getCurrentBorder() const;
|
||||
|
||||
///
|
||||
/// Processes the image. This performs detecion of black-border on the given image and
|
||||
/// updates the current border accordingly. If the current border is updated the method call
|
||||
/// will return true else false
|
||||
///
|
||||
/// @param image The image to process
|
||||
///
|
||||
/// @return True if a different border was detected than the current else false
|
||||
///
|
||||
template <typename Pixel_T>
|
||||
bool process(const Image<Pixel_T> & image)
|
||||
{
|
||||
// get the border for the single image
|
||||
BlackBorder imageBorder = _detector.process(image);
|
||||
// add blur to the border
|
||||
if (imageBorder.horizontalSize > 0)
|
||||
{
|
||||
imageBorder.horizontalSize += _blurRemoveCnt;
|
||||
}
|
||||
if (imageBorder.verticalSize > 0)
|
||||
{
|
||||
imageBorder.verticalSize += _blurRemoveCnt;
|
||||
}
|
||||
|
||||
const bool borderUpdated = updateBorder(imageBorder);
|
||||
return borderUpdated;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
///
|
||||
/// Updates the current border based on the newly detected border. Returns true if the
|
||||
/// current border has changed.
|
||||
///
|
||||
/// @param newDetectedBorder The newly detected border
|
||||
/// @return True if the current border changed else false
|
||||
///
|
||||
bool updateBorder(const BlackBorder & newDetectedBorder);
|
||||
|
||||
/// The number of unknown-borders detected before it becomes the current border
|
||||
const unsigned _unknownSwitchCnt;
|
||||
|
||||
/// The number of horizontal/vertical borders detected before it becomes the current border
|
||||
const unsigned _borderSwitchCnt;
|
||||
|
||||
/// The number of pixels to increase a detected border for removing blury pixels
|
||||
unsigned _blurRemoveCnt;
|
||||
|
||||
/// The blackborder detector
|
||||
BlackBorderDetector _detector;
|
||||
|
||||
/// The current detected border
|
||||
BlackBorder _currentBorder;
|
||||
|
||||
/// The border detected in the previous frame
|
||||
BlackBorder _previousDetectedBorder;
|
||||
|
||||
/// The number of frame the previous detected border matched the incomming border
|
||||
unsigned _consistentCnt;
|
||||
};
|
||||
} // end namespace hyperion
|
Reference in New Issue
Block a user