a b/src/auxiliary.cpp
1
#include "Rcpp.h"
2
#include <opencv2/opencv.hpp>
3
#include "opencv2/xfeatures2d.hpp"
4
#include "opencv2/features2d.hpp"
5
#include "opencv2/shape/shape_transformer.hpp"
6
7
using namespace Rcpp;
8
using namespace std;
9
using namespace cv;
10
using namespace cv::xfeatures2d;
11
12
////
13
// replace NAs in matrices
14
////
15
16
// [[Rcpp::export(rng=false)]]
17
Rcpp::NumericMatrix replaceNaMatrix(Rcpp::NumericMatrix mat, int replace) {
18
  int nrow = mat.nrow();
19
  int ncol = mat.ncol();
20
  
21
  for (int i = 0; i < nrow; i++) {
22
    for (int j = 0; j < ncol; j++) {
23
      if (Rcpp::NumericMatrix::is_na(mat(i, j))) {
24
        mat(i, j) = replace;
25
      }
26
    }
27
  }
28
  return mat;
29
}
30
31
32
////
33
// Conversion
34
////
35
36
// Function to convert a cv::Mat object to a RawVector for magick images
37
Rcpp::RawVector matToImage(cv::Mat mat) {
38
39
  // Create RawVector object
40
  Rcpp::RawVector rawvec(mat.total() * mat.elemSize());
41
  rawvec.attr("dim") = Rcpp::Dimension(3, mat.cols, mat.rows);
42
43
  // Copy Mat data to RawVector
44
  std::memcpy(rawvec.begin(), mat.data, rawvec.size());
45
46
  return rawvec;
47
}
48
49
// Function to convert a RawVector for magick images to a cv::Mat object
50
cv::Mat imageToMat(Rcpp::RawVector image_data, int width, int height) {
51
  
52
  // Create cv::Mat object
53
  cv::Mat mat(height, width, CV_8UC3, image_data.begin());
54
  
55
  // Convert from RGBA to BGRA
56
  cv::cvtColor(mat, mat, cv::COLOR_RGBA2BGR);
57
  
58
  return mat;
59
}
60
61
// Function to convert a NumericMatrix object to a cv::Mat
62
cv::Mat numericMatrixToMat(Rcpp::NumericMatrix nm) {
63
  cv::Mat m(nm.rows(), nm.cols(), CV_64F);
64
  for (int i = 0; i < nm.rows(); ++i) {
65
    for (int j = 0; j < nm.cols(); ++j) {
66
      m.at<double>(i, j) = nm(i, j);
67
    }
68
  }
69
  return m;
70
}
71
72
// Function to convert a NumericMatrix object to a cv::Point2f
73
std::vector<cv::Point2f> numericMatrixToPoint2f(Rcpp::NumericMatrix mat) {
74
  std::vector<cv::Point2f> points;
75
  for (int i = 0; i < mat.nrow(); i++) {
76
    points.push_back(cv::Point2f(mat(i, 0), mat(i, 1)));
77
  }
78
  return points;
79
}
80
81
// Function to convert a cv::Mat object to a NumericMatrix
82
Rcpp::NumericMatrix matToNumericMatrix(cv::Mat m) {
83
  Rcpp::NumericMatrix nm(m.rows, m.cols);
84
  for (int i = 0; i < m.rows; ++i) {
85
    for (int j = 0; j < m.cols; ++j) {
86
      nm(i, j) = m.at<double>(i, j);
87
    }
88
  }
89
  return nm;
90
}
91
92
// Function to convert a cv::Point2f object to a NumericMatrix
93
Rcpp::NumericMatrix point2fToNumericMatrix(std::vector<cv::Point2f> points) {
94
  int n = points.size();
95
  Rcpp::NumericMatrix mat(n, 2);
96
  for (int i = 0; i < n; i++) {
97
    mat(i, 0) = points[i].x;
98
    mat(i, 1) = points[i].y;
99
  }
100
  return mat;
101
}
102
103
// Function to convert a cv::Keypoint object to a std::vector<double>
104
std::vector<double> KeyPointToDoubleVector(std::vector<cv::KeyPoint> points) {
105
  int n = points.size();
106
  std::vector<double> vec(n);
107
  for (int i = 0; i < n; i++) {
108
    vec[i] = (double) points[i].pt.x;
109
  }
110
  return vec;
111
}
112
113
// Function to convert a cv::Point2f object to a std::vector<double>
114
std::vector<double> Point2fToDoubleVector(std::vector<cv::Point2f> points) {
115
  int n = points.size();
116
  std::vector<double> vec(n);
117
  for (int i = 0; i < n; i++) {
118
    vec[i] = (double) points[i].x;
119
  }
120
  return vec;
121
}
122
123
// Function to convert a cv::Point2f object to a cv::Mat
124
std::vector<cv::Point2f> matToPoint2f(cv::Mat mat) {
125
  std::vector<cv::Point2f> points;
126
  
127
  // Assuming the matrix has 2 columns (x and y coordinates)
128
  if (mat.cols != 2) {
129
    // cerr << "Input matrix must have exactly 2 columns for x and y coordinates." << endl;
130
    return points;
131
  }
132
  
133
  // Iterate over the rows of the matrix
134
  for (int i = 0; i < mat.rows; ++i) {
135
    // Extract x and y coordinates from the matrix
136
    float x = mat.at<float>(i, 0);
137
    float y = mat.at<float>(i, 1);
138
    
139
    // Create Point2f object and add it to the vector
140
    points.push_back(Point2f(x, y));
141
  }
142
  
143
  return points;
144
}
145
146
cv::Mat point2fToMat(std::vector<cv::Point2f> points) {
147
  cv::Mat mat(points.size(), 2, CV_32F);
148
  
149
  // Iterate over the vector of Point2f
150
  for (size_t i = 0; i < points.size(); ++i) {
151
    
152
    // Assign x and y coordinates to the matrix
153
    mat.at<float>(i, 0) = points[i].x;
154
    mat.at<float>(i, 1) = points[i].y;
155
  }
156
  
157
  return mat;
158
}
159
160
// calculate standard deviation of a vector
161
double cppSD(std::vector<cv::KeyPoint> points)
162
{
163
  std::vector<double> inVec = KeyPointToDoubleVector(points);
164
  int n = inVec.size();
165
  double sum = std::accumulate(inVec.begin(), inVec.end(), 0.0);
166
  double mean = sum / inVec.size();
167
  
168
  for(std::vector<double>::iterator iter = inVec.begin();
169
      iter != inVec.end(); ++iter){
170
    double temp;
171
    temp= (*iter - mean)*(*iter - mean);
172
    *iter = temp;
173
  }
174
  
175
  double sd = std::accumulate(inVec.begin(), inVec.end(), 0.0);
176
  return std::sqrt( sd / (n-1) );
177
}
178
179
double cppSD(std::vector<cv::Point2f> points)
180
{
181
  std::vector<double> inVec = Point2fToDoubleVector(points);
182
  int n = inVec.size();
183
  double sum = std::accumulate(inVec.begin(), inVec.end(), 0.0);
184
  double mean = sum / inVec.size();
185
  
186
  for(std::vector<double>::iterator iter = inVec.begin();
187
      iter != inVec.end(); ++iter){
188
    double temp;
189
    temp= (*iter - mean)*(*iter - mean);
190
    *iter = temp;
191
  }
192
  
193
  double sd = std::accumulate(inVec.begin(), inVec.end(), 0.0);
194
  return std::sqrt( sd / (n-1) );
195
}