Direct Graphical Models  v.1.7.0
SparseCoding.cpp
1 #include "SparseCoding.h"
2 #include "SparseDictionary.h"
3 #include "LinearMapper.h"
4 #include "macroses.h"
5 
6 namespace DirectGraphicalModels { namespace fex
7 {
8 Mat CSparseCoding::get(const Mat &img, const Mat &D, SqNeighbourhood nbhd)
9 {
10  const word nWords = D.rows;
11  DGM_ASSERT_MSG(nWords <= CV_CN_MAX, "The number of words %d exceeds the maximal allowed number of channels %d. Use get_v() function instead.", nWords, CV_CN_MAX);
12 
13  Mat res;
14  vec_mat_t vFeatures = get_v(img, D, nbhd);
15  merge(vFeatures, res);
16  return res;
17 }
18 
19 vec_mat_t CSparseCoding::get_v(const Mat &img, const Mat &D, SqNeighbourhood nbhd)
20 {
21  DGM_ASSERT_MSG(!D.empty(), "The dictionary must me trained or loaded before using this function");
22 
23  const word nWords = D.rows;
24  const int blockSize = static_cast<int>(sqrt(D.cols));
25  const int dataWidth = img.cols - blockSize + 1;
26  const int dataHeight = img.rows - blockSize + 1;
27 
28  DGM_ASSERT_MSG(nbhd.leftGap + nbhd.rightGap == nbhd.upperGap + nbhd.lowerGap, "The Neighbourhood must be a square for this method");
29  DGM_ASSERT(blockSize == nbhd.leftGap + nbhd.rightGap + 1);
30 
31  Mat X = img2data(img, blockSize);
32  int normalizer = (X.depth() == CV_8U) ? 255 : 65535;
33 
34  vec_mat_t res(nWords);
35  for (word w = 0; w < nWords; w++)
36  res[w] = Mat(img.size(), CV_8UC1, cv::Scalar(0));
37 
38 #ifdef ENABLE_PPL
39  concurrency::parallel_for(0, dataHeight, 1, [&](int y) {
40 #else
41  for (int y = 0; y < dataHeight; y++) {
42 #endif
43  Mat _W, W;
44  for (int x = 0; x < dataWidth; x += 1) {
45  int s = y * dataWidth + x; // sample index
46  Mat sample = X.row(s); // sample as a row-vector
47  sample.convertTo(sample, CV_32FC1, 1.0 / normalizer);
48 
49  gemm(D, sample.t(), 1.0, Mat(), 0.0, _W); // W = D x sample^T
50  W = _W.t();
51  for (int w = 0; w < W.cols; w++)
52  W.col(w) /= norm(D.row(w), NORM_L2);
53 
54  calculate_W(sample, D, W, SC_LAMBDA, SC_EPSILON, 200, SC_LRATE_W);
55 
56  for (word w = 0; w < nWords; w++)
57  res[w].at<byte>(y + nbhd.upperGap, x + nbhd.leftGap) = linear_mapper<byte>(W.at<float>(0, w), -1.0f, 1.0f);
58  }
59  }
60 #ifdef ENABLE_PPL
61  );
62 #endif
63  return res;
64 }
65 } }
int rightGap
Distance from the base point to the neighborhood&#39;s right boundary.
int leftGap
Distance from the base point to the neighborhood&#39;s left boundary.
static void calculate_W(const Mat &X, const Mat &D, Mat &W, float lambda, float epsilon, unsigned int nIt=800, float lRate=SC_LRATE_W)
Evaluates weighting coefficients matrix .
const float SC_LRATE_W
Learning rate (speed) for weights .
const float SC_EPSILON
: L1-regularisation epsilon
virtual Mat get(void) const
Extracts and returns the required feature.
Definition: SparseCoding.h:27
int lowerGap
Distance from the base point to the neighborhood&#39;s lower boundary.
static Mat img2data(const Mat &img, int blockSize, float varianceThreshold=0.0f)
Converts image into data .
int upperGap
Distance from the base point to the neighborhood&#39;s upper boundary.
static vec_mat_t get_v(const Mat &img, const Mat &D, SqNeighbourhood nbhd=sqNeighbourhood(3))
Extracts the sparse coding feature.
const float SC_LAMBDA
: L1-regularisation parameter (on features)