quality_utils.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // This file is part of OpenCV project.
  2. // It is subject to the license terms in the LICENSE file found in the top-level directory
  3. // of this distribution and at http://opencv.org/license.html.
  4. #ifndef OPENCV_QUALITY_QUALITY_UTILS_HPP
  5. #define OPENCV_QUALITY_QUALITY_UTILS_HPP
  6. #include "qualitybase.hpp"
  7. namespace cv
  8. {
  9. namespace quality
  10. {
  11. namespace quality_utils
  12. {
  13. // default type of matrix to expand to
  14. static CV_CONSTEXPR const int EXPANDED_MAT_DEFAULT_TYPE = CV_32F;
  15. // convert inputarray to specified mat type. set type == -1 to preserve existing type
  16. template <typename R>
  17. inline R extract_mat(InputArray in, const int type = -1)
  18. {
  19. R result = {};
  20. if ( in.isMat() )
  21. in.getMat().convertTo( result, (type != -1) ? type : in.getMat().type());
  22. else if ( in.isUMat() )
  23. in.getUMat().convertTo( result, (type != -1) ? type : in.getUMat().type());
  24. else
  25. CV_Error(Error::StsNotImplemented, "Unsupported input type");
  26. return result;
  27. }
  28. // extract and expand matrix to target type
  29. template <typename R>
  30. inline R expand_mat( InputArray src, int TYPE_DEFAULT = EXPANDED_MAT_DEFAULT_TYPE)
  31. {
  32. auto result = extract_mat<R>(src, -1);
  33. // by default, expand to 32F unless we already have >= 32 bits, then go to 64
  34. // if/when we can detect OpenCL CV_16F support, opt for that when input depth == 8
  35. // note that this may impact the precision of the algorithms and would need testing
  36. int type = TYPE_DEFAULT;
  37. switch (result.depth())
  38. {
  39. case CV_32F:
  40. case CV_32S:
  41. case CV_64F:
  42. type = CV_64F;
  43. }; // switch
  44. result.convertTo(result, type);
  45. return result;
  46. }
  47. // return mat of observed min/max pair per column
  48. // row 0: min per column
  49. // row 1: max per column
  50. // template <typename T>
  51. inline cv::Mat get_column_range( const cv::Mat& data )
  52. {
  53. CV_Assert(data.channels() == 1);
  54. CV_Assert(data.rows > 0);
  55. cv::Mat result( cv::Size( data.cols, 2 ), data.type() );
  56. auto
  57. row_min = result.row(0)
  58. , row_max = result.row(1)
  59. ;
  60. // set initial min/max
  61. data.row(0).copyTo(row_min);
  62. data.row(0).copyTo(row_max);
  63. for (int y = 1; y < data.rows; ++y)
  64. {
  65. auto row = data.row(y);
  66. cv::min(row,row_min, row_min);
  67. cv::max(row, row_max, row_max);
  68. }
  69. return result;
  70. } // get_column_range
  71. // linear scale of each column from min to max
  72. // range is column-wise pair of observed min/max. See get_column_range
  73. template <typename T>
  74. inline void scale( cv::Mat& mat, const cv::Mat& range, const T min, const T max )
  75. {
  76. // value = lower + (upper - lower) * (value - feature_min[index]) / (feature_max[index] - feature_min[index]);
  77. // where [lower] = lower bound, [upper] = upper bound
  78. for (int y = 0; y < mat.rows; ++y)
  79. {
  80. auto row = mat.row(y);
  81. auto row_min = range.row(0);
  82. auto row_max = range.row(1);
  83. for (int x = 0; x < mat.cols; ++x)
  84. row.at<T>(x) = min + (max - min) * (row.at<T>(x) - row_min.at<T>(x) ) / (row_max.at<T>(x) - row_min.at<T>(x));
  85. }
  86. }
  87. } // quality_utils
  88. } // quality
  89. } // cv
  90. #endif