1 #ifndef MTF_MISC_UTILS_H 2 #define MTF_MISC_UTILS_H 4 #include "mtf/Macros/common.h" 7 #include <visp3/core/vpImage.h> 8 #include <visp3/core/vpColor.h> 23 template<
typename ValT>
25 int img_width = 0,
int img_height = 0,
int border_size = 0);
27 template<
typename ValT>
28 cv::Rect_<ValT>
getBoundedRectangle(
const cv::Rect_<ValT> &_in_rect,
int img_width,
int img_height,
33 template<
typename PtScalarT>
34 Corners(
const cv::Point_<PtScalarT>(&pt_corners)[4],
35 PtScalarT offset_x = 0, PtScalarT offset_y = 0){
36 corners.create(2, 4, CV_64FC1);
37 for(
unsigned int corner_id = 0; corner_id < 4; ++corner_id) {
38 corners.at<
double>(0, corner_id) = pt_corners[corner_id].x + offset_x;
39 corners.at<
double>(1, corner_id) = pt_corners[corner_id].y + offset_y;
42 template<
typename RectScalarT>
43 Corners(
const cv::Rect_<RectScalarT> rect,
44 RectScalarT offset_x = 0, RectScalarT offset_y = 0){
45 corners.create(2, 4, CV_64FC1);
46 RectScalarT min_x = rect.x + offset_x, min_y = rect.y + offset_y;
47 RectScalarT max_x = min_x + rect.width, max_y = min_y + rect.height;
48 corners.at<
double>(0, 0) = corners.at<
double>(0, 3) = min_x;
49 corners.at<
double>(0, 1) = corners.at<
double>(0, 2) = max_x;
50 corners.at<
double>(1, 0) = corners.at<
double>(1, 1) = min_y;
51 corners.at<
double>(1, 2) = corners.at<
double>(1, 3) = max_y;
53 Corners(
const cv::Mat &mat_corners,
54 double offset_x = 0,
double offset_y = 0){
55 corners = mat_corners.clone();
56 corners.row(0) += offset_x;
57 corners.row(1) += offset_y;
59 Corners(
const CornersT &eig_corners,
60 double offset_x = 0,
double offset_y = 0){
61 corners.create(2, 4, CV_64FC1);
62 for(
unsigned int corner_id = 0; corner_id < 4; ++corner_id){
63 corners.at<
double>(0, corner_id) = eig_corners(0, corner_id) + offset_x;
64 corners.at<
double>(1, corner_id) = eig_corners(1, corner_id) + offset_y;
67 template<
typename RectScalarT>
68 cv::Rect_<RectScalarT> rect(){
69 return getBestFitRectangle<RectScalarT>(corners);
71 template<
typename PtScalarT>
72 void points(cv::Point_<PtScalarT>(&pt_corners)[4]){
73 for(
unsigned int corner_id = 0; corner_id < 4; ++corner_id) {
74 pt_corners[corner_id].x =
static_cast<PtScalarT
>(
75 corners.at<
double>(0, corner_id));
76 pt_corners[corner_id].y =
static_cast<PtScalarT
>(
77 corners.at<
double>(1, corner_id));
80 cv::Mat mat(){
return corners; }
81 void mat(cv::Mat &mat_corners){ mat_corners = corners.clone(); }
87 void eig(CornersT &eig_corners){
88 for(
unsigned int corner_id = 0; corner_id < 4; ++corner_id){
89 eig_corners(0, corner_id) = corners.at<
double>(0, corner_id);
90 eig_corners(1, corner_id) = corners.at<
double>(1, corner_id);
96 template<
typename MatT>
97 inline void printMatrix(
const MatT &eig_mat,
const char* mat_name =
nullptr,
98 const char* fmt =
"%15.9f",
const char *coeff_sep =
"\t",
99 const char *row_sep =
"\n"){
101 printf(
"%s:\n", mat_name);
102 for(
int i = 0; i < eig_mat.rows(); i++){
103 for(
int j = 0; j < eig_mat.cols(); j++){
104 printf(fmt, eig_mat(i, j));
105 printf(
"%s", coeff_sep);
107 printf(
"%s", row_sep);
111 template<
typename ScalarT>
112 inline void printScalar(ScalarT scalar_val,
const char* scalar_name,
113 const char* fmt =
"%15.9f",
const char *name_sep =
"\t",
114 const char *val_sep =
"\n"){
115 fprintf(stdout,
"%s:%s", scalar_name, name_sep);
116 fprintf(stdout, fmt, scalar_val);
117 fprintf(stdout,
"%s", val_sep);
120 template<
typename MatT>
121 inline void printMatrixToFile(
const MatT &eig_mat,
const char* mat_name,
122 const char* fname,
const char* fmt =
"%15.9f",
const char* mode =
"a",
123 const char *coeff_sep =
"\t",
const char *row_sep =
"\n",
124 char**
const row_labels =
nullptr,
const char **mat_header =
nullptr,
125 const char* header_fmt =
"%15s",
const char *name_sep =
"\n"){
131 if((err = fopen_s(&fid, fname, mode)) != 0) {
132 printf(
"File %s could not be opened successfully: %s\n",
133 fname, strerror(err));
136 FILE *fid = fopen(fname, mode);
138 printf(
"File %s could not be opened successfully\n", fname);
143 fprintf(fid,
"%s:%s", mat_name, name_sep);
145 for(
int j = 0; j < eig_mat.cols(); j++){
146 fprintf(fid, header_fmt, mat_header[j]);
147 fprintf(fid,
"%s", coeff_sep);
149 fprintf(fid,
"%s", row_sep);
151 for(
int i = 0; i < eig_mat.rows(); i++){
152 for(
int j = 0; j < eig_mat.cols(); j++){
153 fprintf(fid, fmt, eig_mat(i, j));
154 fprintf(fid,
"%s", coeff_sep);
158 fprintf(fid,
"\t%s", row_labels[i]);
160 fprintf(fid,
"%s", row_sep);
165 template<
typename ScalarT>
166 inline void printScalarToFile(ScalarT scalar_val,
const char* scalar_name,
167 const char* fname,
const char* fmt =
"%15.9f",
const char* mode =
"a",
168 const char *name_sep =
"\t",
const char *val_sep =
"\n"){
173 if((err = fopen_s(&fid, fname, mode)) != 0) {
174 printf(
"File %s could not be opened successfully: %s\n",
175 fname, strerror(err));
178 FILE *fid = fopen(fname, mode);
180 printf(
"File %s could not be opened successfully\n", fname);
186 fprintf(fid,
"%s:%s", scalar_name, name_sep);
187 fprintf(fid, fmt, scalar_val);
188 fprintf(fid,
"%s", val_sep);
192 template<
typename ScalarT,
typename MatT>
193 inline void saveMatrixToFile(
const MatT &eig_mat,
const char* fname,
194 const char* mode =
"ab"){
195 FILE *fid = fopen(fname,
"ab");
197 printf(
"File %s could not be opened successfully\n", fname);
200 fwrite(eig_mat.data(),
sizeof(ScalarT), eig_mat.size(), fid);
204 template<
typename ScalarT>
205 inline void saveScalarToFile(ScalarT &scalar_val,
const char* fname,
206 const char* mode =
"ab"){
207 FILE *fid = fopen(fname, mode);
209 printf(
"File %s could not be opened successfully\n", fname);
212 fwrite(&scalar_val,
sizeof(ScalarT), 1, fid);
217 template<
typename ScalarT>
218 inline void printMatrix(
const cv::Mat &cv_mat,
const char* mat_name,
219 const char* fmt =
"%15.9f",
const char *coeff_sep =
"\t",
220 const char *row_sep =
"\n",
const char *name_sep =
"\n"){
222 printf(
"%s:%s", mat_name, name_sep);
223 for(
int i = 0; i < cv_mat.rows; i++){
224 for(
int j = 0; j < cv_mat.cols; j++){
225 printf(fmt, cv_mat.at<ScalarT>(i, j));
226 printf(
"%s", coeff_sep);
228 printf(
"%s", row_sep);
233 template<
typename ScalarT>
234 inline void printMatrixToFile(
const cv::Mat &cv_mat,
const char* mat_name,
235 const char* fname,
const char* fmt =
"%15.9f",
const char* mode =
"a",
236 const char *coeff_sep =
"\t",
const char *row_sep =
"\n",
237 const char **row_labels =
nullptr,
const char **mat_header =
nullptr,
238 const char* header_fmt =
"%15s",
const char *name_sep =
"\n"){
241 FILE *fid = fopen(fname, mode);
243 printf(
"File %s could not be opened successfully\n", fname);
247 fprintf(fid,
"%s:%s", mat_name, name_sep);
249 for(
int j = 0; j < cv_mat.cols; j++){
250 fprintf(fid, header_fmt, mat_header[j]);
251 fprintf(fid,
"%s", coeff_sep);
253 fprintf(fid,
"%s", row_sep);
255 for(
int i = 0; i < cv_mat.rows; i++){
256 for(
int j = 0; j < cv_mat.cols; j++){
257 fprintf(fid, fmt, cv_mat.at<ScalarT>(i, j));
258 fprintf(fid,
"%s", coeff_sep);
262 fprintf(fid,
"\t%s", row_labels[i]);
264 fprintf(fid,
"%s", row_sep);
269 template<
typename MatT>
270 inline bool hasInf(
const MatT &eig_mat){
271 for(
int row_id = 0; row_id < eig_mat.rows(); row_id++){
272 for(
int col_id = 0; col_id < eig_mat.cols(); col_id++){
273 if(std::isinf(eig_mat(row_id, col_id))){
return true; }
278 template<
typename MatT>
279 inline bool hasNaN(
const MatT &eig_mat){
280 for(
int row_id = 0; row_id < eig_mat.rows(); row_id++){
281 for(
int col_id = 0; col_id < eig_mat.cols(); col_id++){
282 if(std::isnan(eig_mat(row_id, col_id))){
return true; }
287 template<
typename ScalarT>
288 inline bool hasInf(
const cv::Mat &cv_mat){
289 for(
int row_id = 0; row_id < cv_mat.rows; ++row_id){
290 for(
int col_id = 0; col_id < cv_mat.cols; ++col_id){
291 if(std::isinf(cv_mat.at<ScalarT>(row_id, col_id))){
return true; }
296 template<
typename ScalarT>
297 inline bool hasNaN(
const cv::Mat &cv_mat){
298 for(
int row_id = 0; row_id < cv_mat.rows; ++row_id){
299 for(
int col_id = 0; col_id < cv_mat.cols; ++col_id){
300 if(std::isnan(cv_mat.at<ScalarT>(row_id, col_id))){
return true; }
305 template<
typename ScalarT>
306 inline bool isFinite(
const cv::Mat &cv_mat){
307 for(
int row_id = 0; row_id < cv_mat.rows; ++row_id){
308 for(
int col_id = 0; col_id < cv_mat.cols; ++col_id){
309 if(std::isnan(cv_mat.at<ScalarT>(row_id, col_id)) ||
310 std::isinf(cv_mat.at<ScalarT>(row_id, col_id))){
321 const uchar* mask,
int mstep,
int count){
323 for(i = j = 0; i < count; i++)
331 void drawCorners(cv::Mat &img,
const cv::Point2d(&cv_corners)[4],
332 const cv::Scalar corners_col,
const std::string label);
334 void maskVector(VectorXd &masked_vec,
const VectorXd &in_vec,
335 const VectorXb &mask,
int masked_size,
int in_size);
337 VectorXd maskVector(
const VectorXd &in_vec,
338 const VectorXb &mask,
int masked_size,
int in_size);
340 template<
typename MatT>
341 inline void maskMatrixByRow(MatT &masked_mat,
const MatT &in_mat,
342 const VectorXb &mask,
int n_cols){
343 assert(in_mat.cols() == n_cols);
344 assert(in_mat.cols() == mask.size());
345 assert(masked_mat.rows() == in_mat.rows());
347 int masked_size = mask.array().count();
348 masked_mat.resize(NoChange, masked_size);
350 for(
int i = 0; i < n_cols; i++){
351 if(mask(i)){ masked_mat.col(mask_id++) = in_mat.col(i); }
355 template<
typename MatT>
356 inline MatT maskMatrixByRow(
const MatT &in_mat,
357 const VectorXb &mask,
int n_cols){
358 int masked_size = mask.array().count();
359 MatT masked_mat(in_mat.rows(), masked_size);
360 maskMatrixByRow(masked_mat, in_mat, mask, n_cols);
364 template<
typename MatT>
365 inline void maskMatrixByCol(MatT &masked_mat,
const MatT &in_mat,
366 const VectorXb &mask,
int n_rows){
367 assert(in_mat.rows() == n_rows);
368 assert(in_mat.rows() == mask.size());
369 assert(masked_mat.rows() == in_mat.rows());
371 int masked_size = mask.array().count();
372 masked_mat.resize(NoChange, masked_size);
374 for(
int i = 0; i < n_rows; i++){
375 if(mask(i)){ masked_mat.row(mask_id++) = in_mat.row(i); }
379 template<
typename MatT>
380 inline MatT maskMatrixByCol(
const MatT &in_mat,
381 const VectorXb &mask,
int n_rows){
382 int masked_size = mask.array().count();
383 MatT masked_mat(masked_size, in_mat.cols());
384 maskMatrixByRow(masked_mat, in_mat, mask, n_rows);
388 template<
typename ScalarT,
typename EigT>
389 inline void copyCVToEigen(EigT &eig_mat,
const cv::Mat &cv_mat){
390 assert(eig_mat.rows() == cv_mat.rows && eig_mat.cols() == cv_mat.cols);
391 for(
int i = 0; i < cv_mat.rows; i++){
392 for(
int j = 0; j < cv_mat.cols; j++){
393 eig_mat(i, j) = cv_mat.at<ScalarT>(i, j);
399 void copyCVToEigen<double, Matrix3d>(Matrix3d &eig_mat,
const cv::Mat &cv_mat);
401 template<
typename ScalarT>
402 inline MatrixXd copyCVToEigen(
const cv::Mat &cv_mat){
403 MatrixXd eig_mat(cv_mat.rows, cv_mat.cols);
404 copyCVToEigen<MatrixXd, ScalarT>(eig_mat, cv_mat);
408 template<
typename ScalarT,
typename EigT>
409 inline void copyEigenToCV(cv::Mat &cv_mat,
const EigT &eig_mat){
410 assert(cv_mat.rows == eig_mat.rows() && cv_mat.cols == eig_mat.cols());
411 for(
int i = 0; i < cv_mat.rows; i++){
412 for(
int j = 0; j < cv_mat.cols; j++){
413 cv_mat.at<ScalarT>(i, j) = eig_mat(i, j);
419 void copyEigenToCV<double, CornersT>(cv::Mat &cv_mat,
420 const CornersT &eig_mat);
422 template<
typename EigT,
typename ScalarT,
int CVMatT>
423 inline cv::Mat copyEigenToCV(
const EigT &eig_mat){
424 cv::Mat cv_mat(eig_mat.rows(), eig_mat.cols(), CVMatT);
425 copyEigenToCV<EigT, ScalarT>(cv_mat, eig_mat);
428 double writeTimesToFile(vector<double> &proc_times,
429 vector<char*> &proc_labels,
char *time_fname,
int iter_id);
431 void drawRegion(cv::Mat &img,
const cv::Mat &vertices, cv::Scalar col = cv::Scalar(0, 255, 0),
432 int line_thickness = 2,
const char *label =
nullptr,
double font_size = 0.50,
433 bool show_corner_ids =
false,
bool show_label =
false,
int line_type = 0);
435 void drawRegion(vpImage<vpRGBa> &img,
const cv::Mat &vertices, vpColor col = vpColor::green,
436 int line_thickness = 2,
const char *label =
nullptr,
double font_size = 0.50,
437 bool show_corner_ids =
false,
bool show_label =
false,
int line_type = 0);
439 void drawGrid(cv::Mat &img,
const PtsT &grid_pts,
int res_x,
int res_y,
440 cv::Scalar col = cv::Scalar(0, 255, 0),
int thickness = 1);
441 template<
typename ImgValT,
typename PatchValT>
442 void drawPatch(cv::Mat &img,
const cv::Mat &patch,
int n_channels = 1,
int start_x = 0,
int start_y = 0);
443 template<
typename ScalarT>
444 void drawPts(cv::Mat &img,
const cv::Mat &pts, cv::Scalar col,
int radius = 2,
446 void writeCorners(FILE *out_fid,
const cv::Mat &corners,
int frame_id,
bool write_header =
false);
450 const char* toString(
TrackErrT _er_type);
451 template<TrackErrT tracking_err_type>
452 double getTrackingError(
const cv::Mat >_corners,
const cv::Mat &tracker_corners){
453 throw invalid_argument(cv::format(
"Invalid tracking error type provided: %d", tracking_err_type));
455 template<>
double getTrackingError<TrackErrT::MCD>(
const cv::Mat >_corners,
456 const cv::Mat &tracker_corners);
457 template<>
double getTrackingError<TrackErrT::CL>(
const cv::Mat >_corners,
458 const cv::Mat &tracker_corners);
459 template<>
double getTrackingError<TrackErrT::Jaccard>(
const cv::Mat >_corners,
460 const cv::Mat &tracker_corners);
461 double getJaccardError(
const cv::Mat >_corners,
const cv::Mat &tracker_corners,
462 int img_width,
int img_height);
463 double getTrackingError(
TrackErrT tracking_err_type,
464 const cv::Mat >_corners,
const cv::Mat &tracker_corners,
465 FILE *out_fid =
nullptr,
int frame_id = 0,
466 int img_width = 0,
int img_height = 0);
468 cv::Mat readTrackerLocation(
const std::string &file_path);
469 cv::Mat getFrameCorners(
const cv::Mat &img,
int borner_size = 1);
470 mtf::PtsT getFramePts(
const cv::Mat &img,
int borner_size = 1);
471 cv::Point2d getCentroid(
const cv::Mat &corners);
472 template<
typename ScalarT>
473 inline void getCentroid(cv::Point_<ScalarT> ¢roid,
474 const cv::Mat &corners){
475 centroid.x =
static_cast<ScalarT
>((corners.at<
double>(0, 0) + corners.at<
double>(0, 1)
476 + corners.at<
double>(0, 2) + corners.at<
double>(0, 3)) / 4.0);
477 centroid.y =
static_cast<ScalarT
>((corners.at<
double>(1, 0) + corners.at<
double>(1, 1)
478 + corners.at<
double>(1, 2) + corners.at<
double>(1, 3)) / 4.0);
481 inline void getCentroid(Vector2d ¢roid,
482 const cv::Mat &corners){
483 centroid(0) = (corners.at<
double>(0, 0) + corners.at<
double>(0, 1)
484 + corners.at<
double>(0, 2) + corners.at<
double>(0, 3)) / 4.0;
485 centroid(1) = (corners.at<
double>(1, 0) + corners.at<
double>(1, 1)
486 + corners.at<
double>(1, 2) + corners.at<
double>(1, 3)) / 4.0;
490 std::string to_string(T val){
500 template<
typename ElementT>
502 const std::vector<int> &indices){
503 assert(indices.size() == vec.size());
505 for(
unsigned int id = 0;
id < vec.size(); ++id) {
506 vec[indices[id]] = vec_copy[id];
510 template<
typename ElementT>
512 const std::vector<int> &indices){
513 assert(indices.size() == mat.cols);
514 cv::Mat mat_copy(mat.clone());
515 for(
int id = 0;
id < mat.cols; ++id) {
516 mat_copy.col(
id).copyTo(mat.col(indices[
id]));
520 template<
typename ElementT>
522 const std::vector<int> &indices){
523 assert(indices.size() == mat.rows);
524 cv::Mat mat_copy(mat.clone());
525 for(
int id = 0;
id < mat.rows; ++id) {
526 mat_copy.row(
id).copyTo(mat.row(indices[
id]));
529 cv::Mat concatenate(
const cv::Mat img_list[],
int n_images,
int axis);
531 cv::Mat
stackImages(
const std::vector<cv::Mat> &img_list,
int stack_order = 0);
532 std::string getDateTime();
void drawRegion(cv::Mat &img, const cv::Mat &vertices, cv::Scalar col=cv::Scalar(0, 255, 0), int line_thickness=2, const char *label=nullptr, double font_size=0.50, bool show_corner_ids=false, bool show_label=false, int line_type=0)
draw the boundary of the image region represented by the polygon formed by the specified vertices ...
cv::Rect_< ValT > getBoundedRectangle(const cv::Rect_< ValT > &_in_rect, int img_width, int img_height, int border_size=0)
adjust the rectangle bounds so it lies entirely within the image with the given size ...
void rearrangeRows(cv::Mat &mat, const std::vector< int > &indices)
rearrange rows of the matrix according to the given indices
Definition: miscUtils.h:521
cv::Rect_< ValT > getBestFitRectangle(const cv::Mat &corners, int img_width=0, int img_height=0, int border_size=0)
compute the rectangle that best fits an arbitrry quadrilateral in terms of maximizing the Jaccard ind...
convert region corners between various formats
Definition: miscUtils.h:32
cv::Mat stackImages(const std::vector< cv::Mat > &img_list, int stack_order=0)
stack_order :: 0: row major 1 : column major
int icvCompressPoints(T *ptr, const uchar *mask, int mstep, int count)
remove elements from OpenCV Mat or other compatible structures according to the provided binary mask ...
Definition: miscUtils.h:320
void rearrange(std::vector< ElementT > &vec, const std::vector< int > &indices)
rearrange elements in vector according to the given indices
Definition: miscUtils.h:501
void rearrangeCols(cv::Mat &mat, const std::vector< int > &indices)
rearrange columns of the matrix according to the given indices
Definition: miscUtils.h:511
basic functions for preprocessing the raw input image using filtering, resizing and histogram equaliz...
Definition: histUtils.h:20
TrackErrT
functions to handle tracking error computation
Definition: miscUtils.h:449
std::vector< int > rearrangeIntoRegion(const cv::Mat ®ion_corners)
get the indices that will rearrange the given points so that they become consecutive points along the...