OpenCV 找出图像中最小值最大值函数minMaxLoc的使用

 

功能:从一个矩阵中找出全局的最大值和最小值。

函数cv::minMaxLoc找出最大和最小元素的值和他们的位置。极值是遍历整个矩阵找到,或者当掩码不是一个空矩阵时,是通过遍历指定矩阵区域找到。

函数不适用于多通道矩阵,如果需要遍历所有的通道来找到最大和最小值,首先使用函数Mat::reshape转换为单通道矩阵。或者你可以使用函数 extractImageCOI ,mixChannels , or split 来提取特定通道。

函数原型1:

CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal,
                            CV_OUT double* maxVal = 0, CV_OUT Point* minLoc = 0,
                            CV_OUT Point* maxLoc = 0, InputArray mask = noArray());

参数说明:

  • 参数1 src 输入单通道矩阵.

  • 参数1 minVal 返回最小值的指针; 如果不需要输入NULL.

  • 参数 maxVal 返回最大值的指针; 如果不需要输入NULL.

  • 参数 minLoc 返回最小值位置的指针 (二维情况下); 如果不需要输入NULL.

  • 参数 maxLoc 返回最大值位置的指针 (二维情况下); 如果不需要输入NULL.

  • 参数 mask 可选参数,用于选择一个子矩阵.

  • 参考 max, min, compare, inRange, extractImageCOI, mixChannels, split, Mat::reshape

函数原型2:

CV_EXPORTS void minMaxIdx(InputArray src, double* minVal, double* maxVal = 0,
                          int* minIdx = 0, int* maxIdx = 0, InputArray mask = noArray());

参数说明:

  • 参数1 src 输入单通道矩阵.

  • 参数1 minVal 返回最小值的指针; 如果不需要输入NULL.

  • 参数 maxVal 返回最大值的指针; 如果不需要输入NULL.

  • 参数 minIdx 返回最小值位置的指针 ((n维情况下); 如果不需要输入NULL. 否则,它必须指向src.dims元素的一个矩阵, 每个维度里最小元素的坐标按顺序存储.

  • 参数 maxIdx 返回最大值位置的指针 ((n维情况下); 如果不需要输入NULL.

  • 参数 mask 指定矩阵区域.

注意:

在稀疏矩阵中,最小值是只能在非零元素中找到。

当minIdx 不是NULL的时候,他必须有至少两个元素(同maxIdx),即使src是一个单行或者单列矩阵。在OpenCV (跟随MATLAB)中每个矩阵至少要有两个维度。单列矩阵是Mx1 矩阵(因此 minIdx/maxIdx将是(i1,0)/(i2,0)),单行矩阵是 1xN矩阵(因此minIdx/maxIdx 将是(0,j1)/(0,j2))。

函数原型3:

CV_EXPORTS void minMaxLoc(const SparseMat& a, double* minVal,
                          double* maxVal, int* minIdx = 0, int* maxIdx = 0);
 

参数说明:

  • 参数1 a 输入单通道矩阵.

  • 参数2 minVal 返回最小值的指针; 如果不需要输入NULL.

  • 参数3 maxVal 返回最大值的指针; 如果不需要输入NULL.

  • 参数4 minIdx 返回最小值位置的指针 ((n维情况下); 如果不需要输入NULL. 否则,它必须指向src.dims元素的一个矩阵, 每个维度里最小元素的坐标按顺序存储.

  • 参数5 maxIdx 返回最大值位置的指针 ((n维情况下); 如果不需要输入NULL.

代码示例:

#include <iostream>
#include <opencv2/opencv.hpp>
​
int main()
{
    // std::cout << "Hello World!\n";
    cv::Mat image = cv::imread("D:\\OpenCVtest\\images\\juice.png");
    cv::Mat image_re = image.reshape(1);
    double minValue, maxValue;    // 最大值,最小值
    cv::Point  minIdx, maxIdx;    // 最小值坐标,最大值坐标     
    cv::minMaxLoc(image_re, &minValue, &maxValue, &minIdx, &maxIdx);
    std::cout << "最大值:" << maxValue <<"最小值:"<<minValue<<std::endl;
    std::cout << "最大值位置:" << maxIdx << "最小值位置:" << minIdx;
   
    cv::waitKey(0);
​
}

运行结果如下

Mat类的函数reshape

功能:不用拷贝数据转换一个2维矩阵的形状或通道的个数

函数为这些元素制造了一个新的矩阵头,新的矩阵可能会有不同的大小或不同的通道数,如果满足下面条件任何组合都有可能:

  • 没有额外的元素被包含进去新矩阵,也没有元素被排除。所以结果的行数、列数、通道数必须在转换后保持不变。

  • 没有数据拷贝,也就是说这是个 O(1)操作。因此,如果你改变了行的个数,或者操作以其他方式改变了元素行的指数,矩阵必须是连续的,参考:Mat::isContinuous

    例如:假如有一些3维的点的集合存储在一个STL vector中,你想用一个3xN矩阵表示这些点,按下面这样做:

    std::vector<Point3f> vec;
        ...
        Mat pointMat = Mat(vec). // convrt vector to Mat, O(1) operation
                     reshape(1). // make Nx3 1-channel matrix out of Nx1 3-channel.
                                      // Also, an O(1) operation
                      t(); // finally, transpose the Nx3 matrix.
                                  // This involves copying all the elements

    函数原型1:

    Mat reshape(int cn, int rows=0) const;

    参数说明:

  • 参数1 cn 新通道数.如果参数是0,通道数保持不变.

  • 参数2 rows 新通道行数. 如果参数是0,行数保持不变.

函数原型2:

Mat reshape(int cn, int newndims, const int* newsz) const;

函数原型3:

Mat reshape(int cn, const std::vector<int>& newshape) const;

猜你喜欢

转载自blog.csdn.net/jndingxin/article/details/108447110