39 StringUTF8(
"unsigned int ImageGradient::AutoMinModule(const ImageGray &img)") +
40 _(
"Wrong image dimensions."));
43 auto S1 = 0.0, S2 = 0.0, C1 = 0.0, C2 = 0.0;
44 auto max =
MinMax(img).second;
46 for (
auto tmp :
Range(img))
48 S1 += double(
At(tmp).rho) * double(img.
At(tmp));
49 S2 += double(
At(tmp).rho) * double(max - img.
At(tmp));
50 C1 += double(img.
At(tmp));
51 C2 += double(max - img.
At(tmp));
56 thresh = (int)ceil((moy1 + moy2) / 2);
70 for (
auto tmp :
Range(img))
71 if (
At(tmp).rho < thresh)
74 img.
At(tmp) =
At(tmp).theta.value;
87 auto min = std::numeric_limits<unsigned int>::max();
88 auto max = std::numeric_limits<unsigned int>::min();
89 for (
auto tmp :
Range(*
this))
91 if (
At(tmp).rho > max) max =
At(tmp).rho;
92 if (
At(tmp).rho < min) min =
At(tmp).rho;
95 if (max == 0) max = 1;
97 for (
auto tmp :
Range(img))
100 p.
h =
At(tmp).theta.value;
102 if (thres && (
At(tmp).rho < thresh))
105 p.
v = uint8_t(((
At(tmp).rho - min) * 255) / max);
120 for (
size_t y = 2; y <
GetHeight() - 2; y++)
121 for (
size_t x = 2; x <
GetWidth() - 2; x++)
128 auto a =
At(x, y).theta;
129 const auto gx = a.Cos();
130 const auto gy = a.Sin();
132 auto px = double(x) - gy;
133 auto py = double(y) + gx;
134 auto cosine = 0.0, sine = 0.0;
139 a =
At(
size_t(px),
size_t(py)).theta;
145 auto frac = py - floor(py);
146 a =
At(
size_t(px),
size_t(floor(py))).theta;
147 cosine = a.Cos() * (1 - frac);
148 sine = a.Sin() * (1 - frac);
149 a =
At(
size_t(px),
size_t(floor(py)) + 1).theta;
150 cosine += a.Cos() * frac;
151 sine += a.Sin() * frac;
158 auto frac = px - floor(px);
159 a =
At(
size_t(floor(px)),
size_t(py)).theta;
160 cosine = a.Cos() * (1 - frac);
161 sine = a.Sin() * (1 - frac);
162 a =
At(
size_t(floor(px)) + 1,
size_t(py)).theta;
163 cosine += a.Cos() * frac;
164 sine += a.Sin() * frac;
168 auto fracx = px - floor(px);
169 auto fracy = py - floor(py);
170 a =
At(
size_t(floor(px)),
size_t(floor(py))).theta;
171 cosine = a.Cos() * (1 - fracx) * (1 - fracy);
172 sine = a.Sin() * (1 - fracx) * (1 - fracy);
173 a =
At(
size_t(floor(px)),
size_t(floor(py)) + 1).theta;
174 cosine += a.Cos() * (1 - fracx) * fracy;
175 sine += a.Sin() * (1 - fracx) * fracy;
176 a =
At(
size_t(floor(px)) + 1,
size_t(floor(py)) + 1).theta;
177 cosine += a.Cos() * fracx * fracy;
178 sine += a.Sin() * fracx * fracy;
179 a =
At(
size_t(floor(px)) + 1,
size_t(floor(py))).theta;
180 cosine += a.Cos() * fracx * (1 - fracy);
181 sine += a.Sin() * fracx * (1 - fracy);
195 a =
At(
size_t(px),
size_t(py)).theta;
201 double frac = py - floor(py);
202 a =
At(
size_t(px),
size_t(floor(py))).theta;
203 cosine = a.Cos() * (1 - frac);
204 sine = a.Sin() * (1 - frac);
205 a =
At(
size_t(px),
size_t(floor(py)) + 1).theta;
206 cosine += a.Cos() * frac;
207 sine += a.Sin() * frac;
214 double frac = px - floor(px);
215 a =
At(
size_t(floor(px)),
size_t(py)).theta;
216 cosine = a.Cos() * (1 - frac);
217 sine = a.Sin() * (1 - frac);
218 a =
At(
size_t(floor(px)) + 1,
size_t(py)).theta;
219 cosine += a.Cos() * frac;
220 sine += a.Sin() * frac;
224 double fracx = px - floor(px);
225 double fracy = py - floor(py);
226 a =
At(
size_t(floor(px)),
size_t(floor(py))).theta;
227 cosine = a.Cos() * (1 - fracx) * (1 - fracy);
228 sine = a.Sin() * (1 - fracx) * (1 - fracy);
229 a =
At(
size_t(floor(px)),
size_t(floor(py)) + 1).theta;
230 cosine += a.Cos() * (1 - fracx) * fracy;
231 sine += a.Sin() * (1 - fracx) * fracy;
232 a =
At(
size_t(floor(px)) + 1,
size_t(floor(py)) + 1).theta;
233 cosine += a.Cos() * fracx * fracy;
234 sine += a.Sin() * fracx * fracy;
235 a =
At(
size_t(floor(px)) + 1,
size_t(floor(py))).theta;
236 cosine += a.Cos() * fracx * (1 - fracy);
237 sine += a.Sin() * fracx * (1 - fracy);
242 auto dist = AngularDistance<ByteAngle>(angle1, angle2);
243 ans.At(x, y) = (uint8_t)
Twice((
int)dist);
252 for (
auto tmp :
Range(res))
254 res.At(tmp) = pixel::BWWhite;
266 const auto GR_WAIT = 1;
267 const auto GR_WAITLEFT = 2;
268 const auto GR_WAITRIGHT = 3;
269 const auto GR_LEFT = 4;
270 const auto GR_RIGHT = 5;
272 std::vector<size_t> rightlist, leftlist;
276 auto angle =
At(0 ,y).theta;
278 if (
At(0, y) < thresh)
294 for (
size_t x = 1; x <
GetWidth(); x++)
296 auto angle =
At(x, y).theta;
298 if (
At(x, y).rho < thresh)
353 leftlist.push_back(acc);
358 leftlist.push_back(acc);
371 rightlist.push_back(acc);
379 rightlist.push_back(acc);
388 auto suml = 0.0, sumr = 0.0;
389 for (
auto & elem : leftlist)
390 suml += double(elem);
391 if (!leftlist.empty())
392 suml /=
double(leftlist.size());
393 for (
auto & elem : rightlist)
394 sumr += double(elem);
395 if (!rightlist.empty())
396 sumr /=
double(rightlist.size());
397 return (sumr + suml);
408 const auto GR_WAIT = 1;
409 const auto GR_WAITTOP = 2;
410 const auto GR_WAITBOTTOM = 3;
411 const auto GR_TOP = 4;
412 const auto GR_BOTTOM = 5;
414 std::vector<size_t> bottomlist, toplist;
416 for (
size_t x = 1; x <
GetWidth(); x++)
418 auto angle =
At(x).theta;
420 if (
At(x).rho < thresh)
426 mode = GR_WAITBOTTOM;
438 auto angle =
At(x, y).theta;
440 if (
At(x, y) < thresh)
495 toplist.push_back(acc);
500 toplist.push_back(acc);
513 bottomlist.push_back(acc);
521 bottomlist.push_back(acc);
530 auto sumt = 0.0, sumb = 0.0;
531 for (
auto & elem : toplist)
532 sumt += double(elem);
533 if (!toplist.empty())
534 sumt /=
double(toplist.size());
535 for (
auto & elem : bottomlist)
536 sumb += double(elem);
537 if (!bottomlist.empty())
538 sumb /=
double(bottomlist.size());
539 return (sumt + sumb);
ScalarRange< T > Range(T b, T e)
Creates a range [[b, e[[.
std::vector< pixel_type >::reference At(size_t x, size_t y) noexcept
Returns a reference to a pixel.
ImageBW MakeMask() const
Create a mask of the gradients' module.
size_t GetHeight() const noexcept
Image< uint8_t > ImageGray
Grayscale image class.
Image< pixel::RGB< uint8_t >> ImageRGB
Color image class.
double GetHRun() const noexcept
Estimates the mean character width.
ImageGray MakeCurvature() const
Creates an image representing the curvature of the gradients.
ImageGray MakeImageGray() const
Converts to a gray image.
A convenience class for angles units.
ImageRGB MakeImageRGB(bool thres=false) const
Converts to a rgb image.
constexpr TypeInfo< T >::SumType Twice(const T &v) noexcept(noexcept(v+v))
Returns the double of a value.
bool IsSignificant(size_t i) const
Tests if a pixel has a significant gradient.
std::pair< T, T > MinMax(const Image< T > &img, CMP cmp=CMP{})
Returns min and max pixel values.
size_t GetWidth() const noexcept
unsigned int AutoMinModule(const ImageGray &img)
Computes the module significance threshold.
A character string class.
double GetVRun() const noexcept
Estimates the mean character height.
static Angle Atan(double tangent) noexcept(std::is_nothrow_constructible< typename Unit::type >::value)
Computes arc tangent.