使用min和max在Mat中缩放每个单元格

时间:2016-01-18 10:36:07

标签: c++ opencv

我无法找出使用给定范围缩放cv :: Mat中所有单元格的函数。它似乎是一个非常有用的功能,或者我应该手动迭代矩阵吗?

我真正想要做的是缩放CvSVM的训练数据。每列都有各自的原因。

2 个答案:

答案 0 :(得分:4)

没有内置函数可以做到这一点,但可以通过在每个normalize上应用带有参数NORM_MINMAX的{​​{3}}轻松完成。

请参阅示例,其中data是原始数据,scaled是缩放输出,其中每列在[0,1]范围内独立标准化:

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;

int main()
{
    Mat1f data = (Mat1f(3, 4) << 0.1f,  2.f,  30.f,   500.f,
                                 0.55f, 22.f, 330.f,  5500.f,
                                 1.f,   12.f, 3030.f, 50500.f);

    float out_min = 0.f;
    float out_max = 1.f;

    Mat1f scaled(data.rows, data.cols, 0.f);
    for (int c = 0; c < data.cols; ++c)
    {
        normalize(data.col(c), scaled.col(c), out_min, out_max, NORM_MINMAX);
    }

    cout << scaled << endl;

    // Scaled data:

    // 0.0  0.0  0.0  0.0
    // 0.5  1.0  0.1  0.1
    // 1.0  0.5  1.0  1.0

    return 0;
}

答案 1 :(得分:3)

这可以通过使用 normType=NORM_INF 调用cv::normalize()来完成。

示例:

cv::Mat data = (cv::Mat_<float>(2, 4) << 1.f, 2.f, 3.f, 4.f,
                                         5.f, 6.f, 7.f, 8.f);
cv::Mat res;
cv::normalize(data, res, 1, 0, cv::NORM_INF); // scale to [0,1]
std::cout << res;

它将打印:

[0.125, 0.25, 0.375, 0.5;
 0.625, 0.75, 0.875, 1]

编辑: 与Miki的方法类似,如果您希望每列不同的范围,则需要在每列上执行此操作。

假设您希望将[0, i]缩放为i列:

cv::Mat data = (cv::Mat_<float>(2, 4) << 1.f, 2.f, 3.f, 4.f,
                                         5.f, 6.f, 7.f, 8.f);
cv::Mat res(data.size(), data.type());
for (int i = 0; i < data.cols; ++i) {
    cv::normalize(data.col(i), res.col(i), i+1, 0, cv::NORM_INF); // scale to [0,i+1]
}
std::cout << res;

它将打印:

[0.2, 0.66666669, 1.2857143, 2;
   1,          2,         3, 4]