hyperion.ng
BlackBorderDetector.h
1 //#include <iostream>
2 #pragma once
3 
4 // Utils includes
5 #include <utils/Image.h>
6 
7 namespace hyperion
8 {
12  struct BlackBorder
13  {
15  bool unknown;
16 
19 
22 
30  inline bool operator== (const BlackBorder& other) const
31  {
32  if (unknown)
33  {
34  return other.unknown;
35  }
36 
37  return other.unknown==false && horizontalSize==other.horizontalSize && verticalSize==other.verticalSize;
38  }
39  };
40 
47  {
48  public:
53  BlackBorderDetector(double threshold);
54 
62 
63  uint8_t calculateThreshold(double blackborderThreshold);
64 
67  template <typename Pixel_T>
69  {
70  // test center and 33%, 66% of width/heigth
71  // 33 and 66 will check left and top
72  // center will check right and bottom sids
73  int width = image.width();
74  int height = image.height();
75  int width33percent = width / 3;
76  int height33percent = height / 3;
77  int width66percent = width33percent * 2;
78  int height66percent = height33percent * 2;
79  int xCenter = width / 2;
80  int yCenter = height / 2;
81 
82 
83  int firstNonBlackXPixelIndex = -1;
84  int firstNonBlackYPixelIndex = -1;
85 
86  width--; // remove 1 pixel to get end pixel index
87  height--;
88 
89  // find first X pixel of the image
90  for (int x = 0; x < width33percent; ++x)
91  {
92  if (!isBlack(image((width - x), yCenter))
93  || !isBlack(image(x, height33percent))
94  || !isBlack(image(x, height66percent)))
95  {
96  firstNonBlackXPixelIndex = x;
97  break;
98  }
99  }
100 
101  // find first Y pixel of the image
102  for (int y = 0; y < height33percent; ++y)
103  {
104  if (!isBlack(image(xCenter, (height - y)))
105  || !isBlack(image(width33percent, y))
106  || !isBlack(image(width66percent, y)))
107  {
108  firstNonBlackYPixelIndex = y;
109  break;
110  }
111  }
112 
113  // Construct result
114  BlackBorder detectedBorder;
115  detectedBorder.unknown = firstNonBlackXPixelIndex == -1 || firstNonBlackYPixelIndex == -1;
116  detectedBorder.horizontalSize = firstNonBlackYPixelIndex;
117  detectedBorder.verticalSize = firstNonBlackXPixelIndex;
118  return detectedBorder;
119  }
120 
121 
124  template <typename Pixel_T>
126  {
127  // only test the topleft third of the image
128  int width = image.width() /3;
129  int height = image.height() / 3;
130  int maxSize = std::max(width, height);
131 
132  int firstNonBlackXPixelIndex = -1;
133  int firstNonBlackYPixelIndex = -1;
134 
135  // find some pixel of the image
136  for (int i = 0; i < maxSize; ++i)
137  {
138  int x = std::min(i, width);
139  int y = std::min(i, height);
140 
141  const Pixel_T & color = image(x, y);
142  if (!isBlack(color))
143  {
144  firstNonBlackXPixelIndex = x;
145  firstNonBlackYPixelIndex = y;
146  break;
147  }
148  }
149 
150  // expand image to the left
151  for(; firstNonBlackXPixelIndex > 0; --firstNonBlackXPixelIndex)
152  {
153  const Pixel_T & color = image(firstNonBlackXPixelIndex-1, firstNonBlackYPixelIndex);
154  if (isBlack(color))
155  {
156  break;
157  }
158  }
159 
160  // expand image to the top
161  for(; firstNonBlackYPixelIndex > 0; --firstNonBlackYPixelIndex)
162  {
163  const Pixel_T & color = image(firstNonBlackXPixelIndex, firstNonBlackYPixelIndex-1);
164  if (isBlack(color))
165  {
166  break;
167  }
168  }
169 
170  // Construct result
171  BlackBorder detectedBorder;
172  detectedBorder.unknown = firstNonBlackXPixelIndex == -1 || firstNonBlackYPixelIndex == -1;
173  detectedBorder.horizontalSize = firstNonBlackYPixelIndex;
174  detectedBorder.verticalSize = firstNonBlackXPixelIndex;
175  return detectedBorder;
176  }
177 
178 
181  template <typename Pixel_T>
183  {
184  // find X position at height33 and height66 we check from the left side, Ycenter will check from right side
185  // then we try to find a pixel at this X position from top and bottom and right side from top
186  int width = image.width();
187  int height = image.height();
188  int width33percent = width / 3;
189  int height33percent = height / 3;
190  int height66percent = height33percent * 2;
191  int yCenter = height / 2;
192 
193 
194  int firstNonBlackXPixelIndex = -1;
195  int firstNonBlackYPixelIndex = -1;
196 
197  width--; // remove 1 pixel to get end pixel index
198  height--;
199 
200  // find first X pixel of the image
201  int x;
202  for (x = 0; x < width33percent; ++x)
203  {
204  if (!isBlack(image((width - x), yCenter))
205  || !isBlack(image(x, height33percent))
206  || !isBlack(image(x, height66percent)))
207  {
208  firstNonBlackXPixelIndex = x;
209  break;
210  }
211  }
212 
213  // find first Y pixel of the image
214  for (int y = 0; y < height33percent; ++y)
215  {
216  // left side top + left side bottom + right side top + right side bottom
217  if (!isBlack(image(x, y))
218  || !isBlack(image(x, (height - y)))
219  || !isBlack(image((width - x), y))
220  || !isBlack(image((width - x), (height - y))))
221  {
222 // std::cout << "y " << y << " lt " << int(isBlack(color1)) << " lb " << int(isBlack(color2)) << " rt " << int(isBlack(color3)) << " rb " << int(isBlack(color4)) << std::endl;
223  firstNonBlackYPixelIndex = y;
224  break;
225  }
226  }
227 
228  // Construct result
229  BlackBorder detectedBorder;
230  detectedBorder.unknown = firstNonBlackXPixelIndex == -1 || firstNonBlackYPixelIndex == -1;
231  detectedBorder.horizontalSize = firstNonBlackYPixelIndex;
232  detectedBorder.verticalSize = firstNonBlackXPixelIndex;
233  return detectedBorder;
234  }
235 
236 
237 
238  private:
239 
247  template <typename Pixel_T>
248  inline bool isBlack(const Pixel_T & color)
249  {
250  // Return the simple compare of the color against black
251  return color.red < _blackborderThreshold && color.green < _blackborderThreshold && color.blue < _blackborderThreshold;
252  }
253 
254  private:
256  const uint8_t _blackborderThreshold;
257 
258  };
259 } // end namespace hyperion
Provide utility methods for Hyperion class.
Definition: BlackBorderDetector.h:7
int verticalSize
The size of the detected vertical border.
Definition: BlackBorderDetector.h:21
unsigned height() const
Returns the height of the image.
Definition: Image.h:129
BlackBorder process_osd(const Image< Pixel_T > &image)
osd detection mode (find x then y at detected x to avoid changes by osd overlays) ...
Definition: BlackBorderDetector.h:182
Result structure of the detected blackborder.
Definition: BlackBorderDetector.h:12
BlackBorder process(const Image< Pixel_T > &image)
default detection mode (3lines 4side detection)
Definition: BlackBorderDetector.h:68
bool operator==(const BlackBorder &other) const
Compares this BlackBorder to the given other BlackBorder.
Definition: BlackBorderDetector.h:30
unsigned width() const
Returns the width of the image.
Definition: Image.h:119
BlackBorder process_classic(const Image< Pixel_T > &image)
classic detection mode (topleft single line mode)
Definition: BlackBorderDetector.h:125
bool unknown
Falg indicating if the border is unknown.
Definition: BlackBorderDetector.h:15
Definition: Image.h:13
int horizontalSize
The size of the detected horizontal border.
Definition: BlackBorderDetector.h:18
The BlackBorderDetector performs detection of black-borders on a single image.
Definition: BlackBorderDetector.h:46