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);
75 std::vector<unsigned int> histo(m_N * m_N * m_N, 0);
76 m_probas.resize(m_N * m_N * m_N);
77 unsigned int pixels = 0;
78 for (
unsigned int i = 0; i < image.
getSize(); ++i) {
86 for (
unsigned int i = 0; i < histo.size(); ++i) {
87 m_probas[i] =
static_cast<float>(histo[i]) / pixels;
93 if (m_probas.size() != counts.size()) {
96 m_probas.resize(m_N * m_N * m_N);
98 for (
unsigned int count : counts) {
101 for (
unsigned int i = 0; i < m_probas.size(); ++i) {
102 m_probas[i] =
static_cast<float>(counts[i]) / m_numPixels;
108 if (other.m_N != m_N) {
111 if (m_numPixels == 0) {
112 m_probas = other.m_probas;
113 m_numPixels = other.m_numPixels;
116 float malpha = 1.f - alpha;
118 for (
unsigned int i = 0; i < m_probas.size(); ++i) {
119 m_probas[i] = malpha * m_probas[i] + alpha * other.m_probas[i];
127#ifdef VISP_HAVE_OPENMP
128#pragma omp parallel for
130 for (
int i = 0; i < static_cast<int>(image.
getSize()); ++i) {
138 const int h =
static_cast<int>(image.
getHeight()), w =
static_cast<int>(image.
getWidth());
139 const int top =
static_cast<int>(bb.getTop());
140 const int left =
static_cast<int>(bb.getLeft());
141 const int bottom = std::min(h- 1,
static_cast<int>(bb.getBottom()));
142 const int right = std::min(w - 1,
static_cast<int>(bb.getRight()));
143#ifdef VISP_HAVE_OPENMP
144#pragma omp parallel for
146 for (
int i = top; i <= bottom; ++i) {
147 const vpRGBa *colorRow = image[i];
148 float *probaRow = proba[i];
149 for (
int j = left; j <= right; ++j) {
157 if (other.m_N != m_N) {
160 double divergence = 0.0;
161 for (
unsigned int i = 0; i < m_probas.size(); ++i) {
162 if (other.m_probas[i] > 0.0 && m_probas[i] > 0.0) {
163 divergence += m_probas[i] * log(m_probas[i] / other.m_probas[i]);
173 for (
unsigned int i = 0; i < m_probas.size(); ++i) {
174 mixture.m_probas[i] = m_probas[i] * 0.5f + other.m_probas[i] * 0.5f;
177 return (
kl(mixture) + other.
kl(mixture)) / 2.0;
184 for (
unsigned int i = 0; i < m_probas.size(); ++i) {
185 bcoeff += sqrt(m_probas[i] * other.m_probas[i]);
188 return sqrt(1.0 - bcoeff);
193 if (insideMask.m_N != outsideMask.m_N) {
197 unsigned int bins =
static_cast<unsigned int>(insideMask.m_probas.size());
199 std::vector<unsigned int> countsIn(bins, 0), countsOut(bins, 0);
203 std::vector<unsigned int>localCountsIn(bins, 0), localCountsOut(bins, 0);
205 for (
unsigned int i = 0; i < image.
getSize(); ++i) {
207 localCountsIn[index] += (mask.
bitmap[i] > 0);
208 localCountsOut[index] += (mask.
bitmap[i] == 0);
212 for (
unsigned int i = 0; i < bins; ++i) {
213 countsIn[i] += localCountsIn[i];
214 countsOut[i] += localCountsOut[i];
218 insideMask.
build(countsIn);
219 outsideMask.
build(countsOut);
224 if (insideMask.m_N != outsideMask.m_N) {
228 const unsigned int bins =
static_cast<unsigned int>(insideMask.m_probas.size());
230 std::vector<unsigned int> countsIn(bins, 0), countsOut(bins, 0);
232 const int beforeBBStart =
static_cast<int>(bbInside.
getTop()) * image.
getWidth() +
static_cast<int>(bbInside.
getLeft());
233 const int afterBBEnd =
static_cast<int>(bbInside.
getBottom()) * image.
getWidth() +
static_cast<int>(bbInside.
getRight());
234#ifdef VISP_HAVE_OPENMP
238 std::vector<unsigned int>localCountsIn(bins, 0), localCountsOut(bins, 0);
239#ifdef VISP_HAVE_OPENMP
242 for (
int i = 0; i < beforeBBStart; ++i) {
244 ++localCountsOut[index];
246#ifdef VISP_HAVE_OPENMP
249 for (
int i = afterBBEnd; i < static_cast<int>(image.
getSize()); ++i) {
251 ++localCountsOut[index];
254#ifdef VISP_HAVE_OPENMP
257 for (
int i =
static_cast<int>(bbInside.
getTop()); i <
static_cast<int>(round(bbInside.
getBottom())); ++i) {
258 for (
int j =
static_cast<int>(bbInside.
getLeft()); j <
static_cast<int>(round(bbInside.
getRight())); ++j) {
259 const unsigned int bitmapIndex = i * image.
getWidth() + j;
261 const bool pixelInMask = mask.
bitmap[bitmapIndex] > 0;
262 localCountsIn[index] +=
static_cast<unsigned int>(pixelInMask);
263 localCountsOut[index] +=
static_cast<unsigned int>(!pixelInMask);
266#ifdef VISP_HAVE_OPENMP
270 for (
unsigned int i = 0; i < bins; ++i) {
271 countsIn[i] += localCountsIn[i];
272 countsOut[i] += localCountsOut[i];
276 insideMask.
build(countsIn);
277 outsideMask.
build(countsOut);
void build(vpColorHistogram &histogram)
double kl(const vpColorHistogram &other) const
void build(const vpImage< vpRGBa > &image, const vpImage< bool > &mask)
Build the histogram representation and associated color probabilities given an image and a 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
Compute the probabilities of every pixel according to this histogram.
unsigned int colorToIndex(const vpRGBa &p) const
Convert an RGB color to an index that can be used to retrieve the probability of this color The alpha...
void merge(const vpColorHistogram &other, float alpha)
Merge this histogram with an another. This histogram is modified. The probabilities are interpolated ...
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.
Definition of the vpImage class member functions.
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.