Direct Graphical Models  v.1.7.0
TrainEdgePottsCS.cpp
1 #include "TrainEdgePottsCS.h"
2 #include "macroses.h"
3 
4 namespace DirectGraphicalModels
5 {
6 // Calculates the Euclidean distance betwee two feature vectors
7 float calculateContrast(const Mat &featureVector1, const Mat &featureVector2)
8 {
9  Mat fv1, fv2, dfv;
10  float res = 0.0f;
11  int nFeatures = featureVector1.rows;
12 
13  featureVector1.convertTo(fv1, CV_32FC1);
14  featureVector2.convertTo(fv2, CV_32FC1);
15 
16  // distance between feature vectors
17  subtract(fv1, fv2, dfv); // dfv = fv1 - fv2;
18  multiply(dfv, dfv, dfv); // sqr(dfv);
19  for (int i = 0; i < nFeatures; i++)
20  res += dfv.at<float>(i, 0);
21  res = sqrtf(res / nFeatures);
22 
23  fv1.release();
24  fv2.release();
25  dfv.release();
26 
27  return res;
28 }
29 
30 // Charbonnier Penalizer
31 float penalizerChar(float x, float l)
32 {
33  float res = l / sqrt(l*l + x*x);
34  return MAX(FLT_EPSILON, res);
35 }
36 
37 // Perona - Malik Penaliter
38 float penalizerPM(float x, float l)
39 {
40  float res = l*l / (l*l + x*x);
41  return MAX(FLT_EPSILON, res);
42 }
43 
44 // Exponential penalizer
45 float penalizerExp (float x, float l)
46 {
47  float res = expf(-l * x*x);
48  return MAX(FLT_EPSILON, res);
49 }
50 
51 
52 Mat CTrainEdgePottsCS::calculateEdgePotentials(const Mat &featureVector1, const Mat &featureVector2, const vec_float_t &vParams) const
53 {
54  DGM_ASSERT_MSG((vParams.size() == 2) || (vParams.size() == m_nStates + 1), "Wrong number of parameters: %zu. It must be either %d or %u", vParams.size(), 2, m_nStates + 1);
55 
56  Mat res = CTrainEdgePotts::calculateEdgePotentials(featureVector1, featureVector2, vec_float_t(vParams.begin(), vParams.end() - 1));
57  if (featureVector1.empty() || featureVector2.empty()) return res; // no cotrast could be calcilated -> return potts edge potential
58 
59  // Assertions:
60  DGM_ASSERT_MSG((featureVector1.type() == CV_8UC1) && (featureVector2.type() == CV_8UC1),
61  "One (or both) of input feature vectors has either wrong depth or more than one channel");
62  DGM_ASSERT_MSG((featureVector1.size().width == 1) && (featureVector1.size().height == getNumFeatures()),
63  "The first input feature vector has wrong size:(%d, %d)", featureVector1.size().width, featureVector1.size().height);
64  DGM_ASSERT_MSG((featureVector2.size().width == 1) && (featureVector2.size().height == getNumFeatures()),
65  "The second input feature vector has wrong size:(%d, %d)", featureVector2.size().width, featureVector2.size().height);
66 
67  float penalty;
68  float dst = calculateContrast(featureVector1, featureVector2);
69  switch(m_penApproach) {
70  case eP_APP_PEN_CHAR: penalty = penalizerChar(dst, vParams.back()); break;
71  case eP_APP_PEN_PM: penalty = penalizerPM(dst, vParams.back()); break;
72  case eP_APP_PEN_EXP: penalty = penalizerExp(dst, vParams.back()); break;
73  }
74 
75  for (byte s = 0; s < m_nStates; s++) res.at<float>(s, s) = MAX(1.0f, res.at<float>(s, s) * penalty);
76 
77  return res;
78 }
79 }
float penalizerExp(float x, float l)
Charbonnier penalization approach.
word getNumFeatures(void) const
Returns number of features.
Definition: ITrain.h:37
Perrona-Malik penalization approach.
virtual Mat calculateEdgePotentials(const Mat &featureVector1, const Mat &featureVector2, const vec_float_t &vParams) const
Returns the data-independent edge potentials.
Exponential penalization approach.
float penalizerChar(float x, float l)
float calculateContrast(const Mat &featureVector1, const Mat &featureVector2)
byte m_nStates
The number of states (classes)
virtual Mat calculateEdgePotentials(const Mat &featureVector1, const Mat &featureVector2, const vec_float_t &vParams) const
Returns the contrast-sensitive edge potentials.
float penalizerPM(float x, float l)