66 size_t q = src.
Size() / compression;
67 size_t r = src.
Size() % compression;
78 datatype(newsize, 0).swap(bins);
81 for (
size_t i = 0; i < q; i++)
85 for (
unsigned int j = 0; j < c; j++)
98 for (
size_t j = k; j < src.
Size(); j++)
122 if (k >= bins.size())
125 _(
"invalid index."));
144 if (k >= bins.size())
147 _(
"invalid index."));
167 if (k >= bins.size())
170 _(
"invalid index."));
187 unsigned int Cumul = 0;
189 for (
auto & elem : bins)
210 for (
size_t k = 0; k < bins.size(); k++)
212 m += double(k * bins[k]);
236 for (
size_t k = 0; k < bins.size(); k++)
238 double d = double(k) - m;
240 v += d * d * bins[k];
263 for (
size_t k = 0; k < bins.size(); k++)
265 double d = double(k) - m;
267 v += d * d * bins[k];
288 for (
auto & elem : bins)
306 unsigned int m = bins[0];
308 for (
auto & elem : bins)
329 for (
size_t k = 0; k < bins.size(); k++)
331 unsigned int v = bins[k];
353 unsigned int m = bins[0];
356 for (
size_t k = 0; k < bins.size(); k++)
358 unsigned int v = bins[k];
380 for (
auto & elem : bins)
397 unsigned int c =
Max();
402 _(
"flat histogram."));
406 double s = (double) m / (
double) c;
408 for (
auto & elem : bins)
410 unsigned int v = (
unsigned int)(elem * s);
427 datatype H(bins.size());
429 for (
size_t k = 0; k < bins.size(); k++)
431 int left =
crn::Max(0,
int(k) -
int(d));
432 int right =
crn::Min(
int(bins.size()) - 1,
int(k) + int(d));
435 uint64_t n = right - left + 1;
437 for (
int j = left; j <= right; j++)
442 H[k] = (
unsigned int)(m / n);
462 _(
"window larger than histogram. Cropping."));
466 datatype H(bins.size());
468 for (
size_t k = 0; k < bins.size(); k++)
470 int left = int(k) - int(d);
471 int right = int(k + d);
473 double n = double(right) - double(left) + 1;
475 for (
int j = left; j <= right; j++)
478 if (index < 0) index = int(bins.size()) + index;
479 if (index >=
int(bins.size())) index -= int(bins.size());
480 m += (double) bins[index] / n;
483 H[k]=(
unsigned int)m;
499 std::vector<size_t> modes;
502 if (bins.size() == 1)
508 if (bins[0] > bins[1])
510 for (
size_t b = 1; b < bins.size() - 1; ++b)
512 if (bins[b] > bins[b - 1])
515 if (bins[b] < bins[b + 1])
519 while (bins[b] == bins[b + 1])
522 if (b == bins.size() - 1)
524 modes.push_back((first + bins.size() - 1) / 2);
527 else if (b == bins.size() - 2)
529 if (bins[b] == bins[b + 1])
531 modes.push_back((first + bins.size() - 1) / 2);
533 if (bins[b] > bins[b + 1])
535 modes.push_back((first + b) / 2);
540 if ((b < bins.size() - 1) && (bins[b] > bins[b + 1]))
542 modes.push_back((first + b) / 2);
546 if (bins[bins.size() - 2] < bins[bins.size() - 1])
547 modes.push_back(bins.size() - 1);
565 std::map<size_t, size_t> mcount;
566 std::map<size_t, std::vector<size_t> > msum;
568 std::vector<size_t> modes(s.
Modes());
569 size_t nmodes = modes.size();
573 auto cit = mcount.find(nmodes);
574 if (cit != mcount.end())
577 auto sit = msum.find(nmodes);
578 std::transform(sit->second.begin(), sit->second.end(), modes.begin(), sit->second.begin(), std::plus<size_t>());
582 mcount.insert(std::make_pair(nmodes, 1));
583 msum.insert(std::make_pair(nmodes, modes));
588 nmodes = modes.size();
601 for (
auto & elem : mcount)
603 if (elem.second > maxpop)
605 maxpop = elem.second;
612 return std::vector<size_t>();
614 modes.swap(msum[nmodes]);
615 std::transform(modes.begin(), modes.end(), modes.begin(), std::bind2nd(std::divides<size_t>(), maxpop));
631 if (bins.size() != h.
Size())
634 _(
"histograms must have same size."));
639 for (
size_t k = 0; k < bins.size(); k++)
659 if (bins.size() != h.
Size())
662 "const Histogram &h): ") +
_(
"histograms must have same size."));
665 double cumulMin = 0.0;
668 for (
size_t k = 0; k < bins.size(); k++)
673 return (1.0 - (cumulMin / cumulH));
688 if (bins.size() != h.
Size())
691 "const Histogram &h): ") +
_(
"histograms must have same size."));
697 double cumul_numer = 0.0;
698 double cumul_denom_1 = 0.0;
699 double cumul_denom_2 = 0.0;
701 for (
size_t k = 0; k < bins.size(); k++)
703 int v_1 = int(bins[k]) - offset_1;
704 int v_2 = int(h.bins[k]) - offset_2;
706 cumul_numer += v_1 * v_2;
707 cumul_denom_1 += v_1 * v_1;
708 cumul_denom_2 += v_2 * v_2;
711 cumul_numer /= sqrt(cumul_denom_1);
712 cumul_numer /= sqrt(cumul_denom_2);
730 if (bins.size() != h.
Size())
733 "const Histogram &h): ") +
_(
"histograms must have same size."));
737 double cumul_numer = 0.0;
738 double cumul_denom = 0.0;
740 for (
size_t k = 0; k < bins.size(); k++)
742 auto v_1 = int(bins[k]);
743 auto v_2 = int(h.bins[k]);
744 int diff = v_1 - v_2;
746 cumul_numer += diff * diff;
747 cumul_denom += v_1 + v_2;
750 return cumul_numer / cumul_denom;
768 if (bins.size() != h.
Size())
771 "const Histogram &h, double r): ") +
772 _(
"histograms must have same size."));
776 double invR = 1.0 / (double)(r);
778 for (
size_t k = 0; k < bins.size(); k++)
780 cumul += pow(fabs((
double)(h.
GetBin(k)) - (
double)(bins[k])),r);
783 return pow(cumul, invR);
800 if (bins.size() != h.
Size())
803 _(
"histograms must have same size."));
808 for (
size_t k = 0; k < bins.size(); k++)
812 double m = (h1 + h2) / 2.0;
814 cumul += h1 * log(h1 / m) + h2 * log(h2 / m);
834 if (bins.size() != h.
Size())
837 _(
"histograms must have same size."));
841 double cumulH1 = 0.0;
842 double cumulH2 = 0.0;
844 for (
size_t k = 0; k < bins.size(); k++)
848 cumul += fabs(cumulH1 - cumulH2);
868 if (bins.size() != h.
Size())
871 "const Histogram &h): ")+
_(
"histograms must have same size."));
875 double cumulH1 = 0.0;
876 double cumulH2 = 0.0;
878 for (
size_t k = 0; k < bins.size(); k++)
882 double diff = fabs(cumulH1 - cumulH2);
903 if (bins.size() != h.
Size())
913 dist += double(
Abs(
int(h1[tmp]) -
int(h2[tmp])));
914 return dist / double(h1.Size());
927 if (bins.size() != h.
Size())
931 auto dist = std::numeric_limits<double>::max();
941 for (
auto i = k; i <
Size(); ++i)
947 for (
auto i =
size_t(0); i < k; ++i)
951 for (
auto j =
size_t(0); j <= i; ++j)
958 for (
auto i = k; i <
Size(); ++i)
959 for (
auto j = k; j <= i; ++j)
967 d +=
double(
Abs(
int(h1[tmp]) -
int(h2[tmp])));
972 return dist / double(
Size());
994 bins.insert(bins.end(), h.bins.begin(), h.bins.end());
1014 if (newsize == bins.size())
1017 datatype newbins(newsize);
1019 double ratio = (double)bins.size() / (double)newsize;
1021 for (
size_t tmp = 0; tmp < newsize; tmp++)
1024 auto end = double(tmp + 1) * ratio;
1025 if (end >=
double(bins.size())) end = double(bins.size()) - 0.0001;
1027 while (floor(tb) != floor(end))
1029 double te = ceil(tb);
1030 if (te == tb) te += 1;
1031 val += (te - tb) * bins[(
size_t)floor(tb)];
1034 val += (end - tb) * bins[(
size_t)floor(tb)];
1035 if ((end - begin) != 0)
1036 val /= (end - begin);
1039 newbins[tmp] = (
unsigned int)round(val);
1065 _(
"Wrong XML element."));
1071 _(
"Cannot get CDATA."));
1074 auto v = Data::ASCII85Decode<unsigned int>(t.
GetValue());
1078 _(
"Cannot convert CDATA."));
1096 auto text =
Data::ASCII85Encode(reinterpret_cast<const uint8_t * const>(bins.data()), bins.size() *
sizeof(datatype::value_type));
1097 xml::Text t(el.PushBackText(text,
false));
1109 String s(U
"Histogram: ");
1110 for (
auto & elem : bins)
1130 auto bw =
ImageBW(bins.size(), height, pixel::BWWhite);
1131 auto val = double(height) / double(
Max());
1132 for (
size_t k = 0; k < bins.size(); k++)
1135 for (
int i = 0; i < int(
double(bin) * val) - 1; ++i)
1137 bw.At(k, height - 1 - i) = pixel::BWBlack;
1148 unsigned int sum = 0;
1149 for (
size_t k = 0; k < bins.size(); k++)
1171 for (
size_t tmp = 0; tmp < bins.size(); tmp++)
1173 double tx = double(
GetBin(tmp) * radius) / max * cos(
double(tmp) * factor);
1174 double ty = double(
GetBin(tmp) * radius) / max * sin(
double(tmp) * factor);
1175 r |=
Rect((
int)tx, (
int)ty);
1180 for (
size_t tmp = 0; tmp < bins.size(); tmp++)
1182 double tx = double(
GetBin(tmp) * radius) / max * cos(
double(tmp) * factor);
1183 double ty = double(
GetBin(tmp) * radius) / max * sin(
double(tmp) * factor);
1185 (int)ty - r.
GetTop(), pixel::BWBlack);
1200 std::vector<bool> notempty(bins.size());
1201 std::vector<double> tab(bins.size());
1203 for (
size_t tmp = 0; tmp < bins.size(); tmp++)
1207 notempty[tmp] =
true;
1208 tab[tmp] = double((tmp + 1) * bins[tmp]);
1212 notempty[tmp] =
false;
1217 double s1 = 0, s2 = 0;
1218 long n1 = 0, n2 = 0;
1219 for (
size_t tmp = 0; tmp < bins.size(); tmp++)
1231 if (notempty[index])
1241 f = double(index) - ((s1 / double(n1)) + (s2 /
double(n2))) / 2.0;
1243 }
while ((index < bins.size()) && (f <= 0.0));
1261 std::vector<double> entropy(bins.size());
1262 for (
size_t tmp = 0; tmp < bins.size(); tmp++)
1265 entropy[tmp] = bins[tmp] * log((
double)bins[tmp]);
1271 for (
size_t t = 0; t < bins.size(); t++)
1273 double s1 = 0, s2 = 0, n1 = 0, n2 = 0;
1274 for (
size_t tmp = 0; tmp <= t; tmp++)
1280 for (
size_t tmp = t + 1; tmp < bins.size(); tmp++)
1288 en = -(s1/n1) - (s2/n2) + log(n1*n2);
1313 for (
auto & elem : bins)
1315 auto b_k = double(elem);
1319 auto p_k = double(b_k / c);
1321 e += p_k * log(p_k);
1342 unsigned int sum = 0;
1344 for (index = 0; index < bins.size(); index++)
1363 for (
auto & elem : bins)
1372 Cloner::Register<Histogram>();
1373 Ruler::Register<Histogram>();
virtual StringUTF8 GetValue() const override
Gets the content of the node.
Image< pixel::BW > ImageBW
Black and white image class.
xml::Element Serialize(xml::Element &parent) const
Dumps the object to an XML element. Unsafe.
ScalarRange< T > Range(T b, T e)
Creates a range [[b, e[[.
double JeffreyDivergence(const Histogram &h) const
Jeffrey divergence between two histograms.
double Entropy() const
the entropy
double IntersectionDivergence(const Histogram &h) const
Intersection divergence between two histograms.
void Deserialize(xml::Element &el)
Initializes the object from an XML element. Unsafe.
void CircularAverageSmoothing(size_t d)
Smoothing circular histogram.
double KolmogorovSmirnovDistance(const Histogram &h) const
Kolmogorov-Smirnov distance between two histograms.
void IncBin(size_t k, unsigned int i=1u)
Increments a bin value.
const T & Max(const T &a, const T &b)
Returns the max of two values.
Text AsText()
Converts to text.
Unintialized object error.
unsigned int Max() const
Maximal count value.
void SetCeiling(unsigned int m)
Set maximal count value to m.
#define CRN_END_CLASS_CONSTRUCTOR(classname)
Defines a class constructor.
int GetTop() const
Returns the topmost coordinate.
size_t Argmax() const
First class having a maximal count value.
size_t Argmin() const
First class having a minimal count value.
int GetLeft() const
Returns the leftmost coordinate.
unsigned int GetBin(size_t k) const
Get a bin value.
ImageBW MakeRadialImageBW(size_t radius) const
returns the circular histogram image
A UTF32 character string class.
double Mean() const
Mean value on class indexes.
Histogram MakeIntersection(const Histogram &h) const
Intersection between two histograms.
void Append(const Histogram &h)
Appends an histogram to the current.
double EMD(const Histogram &h) const
Earth Mover's Distance.
ImageBW MakeImageBW(size_t height) const
returns the histogram image
void SetBin(size_t k, unsigned int v)
Modify a bin value.
double Variance() const
Variance on class indexes.
#define CRN_DATA_FACTORY_REGISTER(elemname, classname)
Registers a class to the data factory.
size_t Size() const noexcept
Returns the number of bins.
constexpr TypeInfo< T >::SumType Twice(const T &v) noexcept(noexcept(v+v))
Returns the double of a value.
virtual StringUTF8 GetValue() const
Gets the content of the node.
void Cumulate()
Cumulates the values from 0 to end.
double Correlation(const Histogram &h) const
Correlation between two histograms.
void DrawLine(size_t x1, size_t y1, size_t x2, size_t y2, pixel_type color)
Draws a line using a specified color.
double Chi2(const Histogram &h) const
Correlation between two histograms.
Node GetFirstChild()
Gets the first child node.
size_t MedianValue() const
Computes the median value.
std::vector< size_t > Modes() const
Returns the modes.
int GetHeight() const
Returns the height of the rectangle.
void Abs(Image< T > &img, typename std::enable_if< std::is_arithmetic< T >::value >::type *dummy=nullptr) noexcept
Replaces each pixel by its absolute value.
std::vector< size_t > StableModes() const
Returns the stable modes.
size_t Fisher() const
Computes the Fisher threshold.
const T & Min(const T &a, const T &b)
Returns the min of two values.
double MinkowskiDistance(const Histogram &h, double r) const
Minkowski distance between two histograms.
Mother class for integer histograms.
Histogram()
Default constructor.
void AverageSmoothing(size_t d)
Smoothing histogram.
double CEMD(const Histogram &h) const
Circular Earth Mover's Distance.
int GetWidth() const
Returns the width of the rectangle.
Histogram MakePopulationHistogram() const
Creates an histogram from population.
size_t EntropyThreshold() const
Computes the entropy threshold.
String ToString() const
Dumps bins to a string.
A character string class.
unsigned int Min() const
Minimal count value.
unsigned int CumulateBins() const
Cumulate all bins.
crn::StringUTF8 ASCII85Encode(const uint8_t *const data, size_t len)
Encodes any data into a printable string.
void ScaleMaxTo(unsigned int m)
Scale maximal count to m.
Element PushBackElement(const StringUTF8 &name)
Adds an element at the end of the children list.
Invalid argument error (e.g.: nullptr pointer)
double MatchDistance(const Histogram &h) const
Match distance between two histograms.
#define CRN_BEGIN_CLASS_CONSTRUCTOR(classname)
Defines a class constructor.
An item was not found in a container.
void Resize(size_t newsize)
Resizes the histogram.