31 #include <visp3/rbt/vpColorHistogram.h>
33 #include <visp3/core/vpImage.h>
34 #include <visp3/core/vpRect.h>
43 unsigned int count = 0;
44 for (
unsigned int i = 0; i < m_counts.size(); ++i) {
47 const float countFloat =
static_cast<float>(count);
48 for (
unsigned int i = 0; i < m_counts.size(); ++i) {
49 histogram.m_probas[i] =
static_cast<float>(m_counts[i]) / countFloat;
51 histogram.m_numPixels = count;
64 if (N != 1 && N != 2 && N != 4 && N != 8 && N != 16 && N != 32 && N != 64 && N != 128) {
68 m_binSize = 256 / m_N;
70 m_probas = std::vector<float>(N * N * N, 0.f);
77 std::vector<unsigned int> histo(m_N * m_N * m_N, 0);
78 m_probas.resize(m_N * m_N * m_N);
79 unsigned int pixels = 0;
80 for (
unsigned int i = 0; i < image.
getSize(); ++i) {
88 for (
unsigned int i = 0; i < histo.size(); ++i) {
89 m_probas[i] =
static_cast<float>(histo[i]) / pixels;
95 if (m_probas.size() != counts.size()) {
98 m_probas.resize(m_N * m_N * m_N);
100 for (
unsigned int count : counts) {
101 m_numPixels += count;
103 for (
unsigned int i = 0; i < m_probas.size(); ++i) {
104 m_probas[i] =
static_cast<float>(counts[i]) / m_numPixels;
110 if (other.m_N != m_N) {
113 float malpha = 1.f - alpha;
115 for (
unsigned int i = 0; i < m_probas.size(); ++i) {
116 m_probas[i] = malpha * m_probas[i] + alpha * other.m_probas[i];
125 #pragma omp parallel for schedule(static)
126 for (
unsigned int i = 0; i < image.
getSize(); ++i) {
134 const int h =
static_cast<int>(image.
getHeight()), w =
static_cast<int>(image.
getWidth());
135 const int top =
static_cast<int>(bb.
getTop());
136 const int left =
static_cast<int>(bb.
getLeft());
137 const int bottom = std::min(h- 1,
static_cast<int>(bb.
getBottom()));
138 const int right = std::min(w - 1,
static_cast<int>(bb.
getRight()));
139 #pragma omp parallel for
140 for (
unsigned int i = top; i <= static_cast<unsigned int>(bottom); ++i) {
141 const vpRGBa *colorRow = image[i];
142 float *probaRow = proba[i];
143 for (
unsigned int j = left; j <= static_cast<unsigned int>(right); ++j) {
153 if (other.m_N != m_N) {
156 double divergence = 0.0;
157 for (
unsigned int i = 0; i < m_probas.size(); ++i) {
158 if (other.m_probas[i] > 0.0 && m_probas[i] > 0.0) {
159 divergence += m_probas[i] * log(m_probas[i] / other.m_probas[i]);
169 for (
unsigned int i = 0; i < m_probas.size(); ++i) {
170 mixture.m_probas[i] = m_probas[i] * 0.5 + other.m_probas[i] * 0.5;
173 return (
kl(mixture) + other.
kl(mixture)) / 2.0;
180 for (
unsigned int i = 0; i < m_probas.size(); ++i) {
181 bcoeff += sqrt(m_probas[i] * other.m_probas[i]);
184 return sqrt(1.0 - bcoeff);
189 if (insideMask.m_N != outsideMask.m_N) {
193 unsigned int bins = insideMask.m_probas.size();
195 std::vector<unsigned int> countsIn(bins, 0), countsOut(bins, 0);
199 std::vector<unsigned int>localCountsIn(bins, 0), localCountsOut(bins, 0);
201 for (
unsigned int i = 0; i < image.
getSize(); ++i) {
203 localCountsIn[index] += mask.
bitmap[i] > 0;
204 localCountsOut[index] += mask.
bitmap[i] == 0;
208 for (
unsigned int i = 0; i < bins; ++i) {
209 countsIn[i] += localCountsIn[i];
210 countsOut[i] += localCountsOut[i];
214 insideMask.
build(countsIn);
215 outsideMask.
build(countsOut);
220 if (insideMask.m_N != outsideMask.m_N) {
224 const unsigned int bins = insideMask.m_probas.size();
226 std::vector<unsigned int> countsIn(bins, 0), countsOut(bins, 0);
228 const unsigned int beforeBBStart =
static_cast<unsigned int>(bbInside.
getTop()) * image.
getWidth() +
static_cast<unsigned int>(bbInside.
getLeft());
229 const unsigned int afterBBEnd =
static_cast<unsigned int>(bbInside.
getBottom()) * image.
getWidth() +
static_cast<unsigned int>(bbInside.
getRight());
233 std::vector<unsigned int>localCountsIn(bins, 0), localCountsOut(bins, 0);
234 #pragma omp for schedule(static, 64)
235 for (
unsigned int i = 0; i < beforeBBStart; ++i) {
237 ++localCountsOut[index];
239 #pragma omp for schedule(static, 64)
240 for (
unsigned int i = afterBBEnd; i < image.
getSize(); ++i) {
242 ++localCountsOut[index];
244 #pragma omp for schedule(static, 64)
245 for (
unsigned int i =
static_cast<unsigned int>(bbInside.
getTop()); i <
static_cast<unsigned int>(round(bbInside.
getBottom())); ++i) {
246 for (
unsigned int j =
static_cast<unsigned int>(bbInside.
getLeft()); j <
static_cast<unsigned int>(round(bbInside.
getRight())); ++j) {
247 const unsigned int bitmapIndex = i * image.
getWidth() + j;
249 const bool pixelInMask = mask.
bitmap[bitmapIndex] > 0;
250 localCountsIn[index] +=
static_cast<unsigned int>(pixelInMask);
251 localCountsOut[index] +=
static_cast<unsigned int>(!pixelInMask);
256 for (
unsigned int i = 0; i < bins; ++i) {
257 countsIn[i] += localCountsIn[i];
258 countsOut[i] += localCountsOut[i];
262 insideMask.
build(countsIn);
263 outsideMask.
build(countsOut);
void build(vpColorHistogram &histogram)
double kl(const vpColorHistogram &other) const
void build(const vpImage< vpRGBa > &image, const vpImage< bool > &mask)
double hellinger(const vpColorHistogram &other) const
unsigned int getBinNumber() const
static void computeSplitHistograms(const vpImage< vpRGBa > &image, const vpImage< bool > &mask, vpColorHistogram &inMask, vpColorHistogram &outsideMask)
void setBinNumber(unsigned int N)
Change the number of bins per color component that the histogram has After calling this method,...
void computeProbas(const vpImage< vpRGBa > &image, vpImage< float > &proba) const
unsigned int colorToIndex(const vpRGBa &p) const
void merge(const vpColorHistogram &other, float alpha)
double jsd(const vpColorHistogram &other) const
error that can be emitted by ViSP classes.
@ badValue
Used to indicate that a value is not in the allowed range.
@ dimensionError
Bad dimension.
unsigned int getWidth() const
void resize(unsigned int h, unsigned int w)
resize the image : Image initialization
unsigned int getSize() const
Type * bitmap
points toward the bitmap
unsigned int getHeight() const
Defines a rectangle in the plane.