一杯清酒邀明月
天下本无事,庸人扰之而烦耳。

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

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

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

函数原型1:

1 CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal,
2                             CV_OUT double* maxVal = 0, CV_OUT Point* minLoc = 0,
3                             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:

1 CV_EXPORTS void minMaxIdx(InputArray src, double* minVal, double* maxVal = 0,
2                           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:

1 CV_EXPORTS void minMaxLoc(const SparseMat& a, double* minVal,
2                           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.

代码示例:

 1 #include <iostream>
 2 #include <opencv2/opencv.hpp>
 3  4 int main()
 5 {
 6     // std::cout << "Hello World!\n";
 7     cv::Mat image = cv::imread("D:\\OpenCVtest\\images\\juice.png");
 8     cv::Mat image_re = image.reshape(1);
 9     double minValue, maxValue;    // 最大值,最小值
10     cv::Point  minIdx, maxIdx;    // 最小值坐标,最大值坐标     
11     cv::minMaxLoc(image_re, &minValue, &maxValue, &minIdx, &maxIdx);
12     std::cout << "最大值:" << maxValue <<"最小值:"<<minValue<<std::endl;
13     std::cout << "最大值位置:" << maxIdx << "最小值位置:" << minIdx;
14    
15     cv::waitKey(0);
16 17 }

运行结果如下

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

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

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

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

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

1 td::vector<Point3f> vec;
2     ...
3     Mat pointMat = Mat(vec). // convrt vector to Mat, O(1) operation
4                  reshape(1). // make Nx3 1-channel matrix out of Nx1 3-channel.
5                                   // Also, an O(1) operation
6                   t(); // finally, transpose the Nx3 matrix.
7                               // 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;

 

posted on 2021-09-26 15:59  一杯清酒邀明月  阅读(6404)  评论(0编辑  收藏  举报