- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
在OpenCV的CUDA模块中,矩阵最大最小值查找操作用于快速获取矩阵中的全局最小值、最大值及其位置。这些函数对于图像处理任务特别有用,例如特征检测和阈值处理。
主要函数
1. [查找矩阵的全局最小值和最大值] cv::cuda::minMax
原型
cpp
void cv::cuda::minMax
(
InputArray src, // 输入数组(通常是 cv::cuda::GpuMat)
double* minVal, // 输出指针,用于接收最小值
double* maxVal, // 输出指针,用于接收最大值
InputArray mask = noArray() // 可选掩码,默认为无掩码
);
参数
- src: 输入矩阵。
- minVal: 输出指针,用于接收最小值。
- maxVal: 输出指针,用于接收最大值。
- mask: 可选掩码,指定哪些元素参与计算,默认为无掩码。
2. [查找矩阵的全局最小值、最大值及其位置] cv::cuda::minMaxLoc
原型
cpp
void cv::cuda::minMaxLoc
(
InputArray src, // 输入数组
double* minVal, // 输出指针,用于接收最小值
double* maxVal, // 输出指针,用于接收最大值
Point* minLoc, // 输出指针,用于接收最小值的位置坐标
Point* maxLoc, // 输出指针,用于接收最大值的位置坐标
InputArray mask = noArray() // 可选掩码
);
参数
- src: 输入矩阵。
- minVal: 输出指针,用于接收最小值。
- maxVal: 输出指针,用于接收最大值。
- minLoc: 输出指针,用于接收最小值的位置坐标。
- maxLoc: 输出指针,用于接收最大值的位置坐标。
- mask: 可选掩码。
3. [将最小值和最大值写入输出数组] cv::cuda::findMinMax
原型
cpp
void cv::cuda::findMinMax
(
InputArray src, // 输入数组
OutputArray dst, // 输出数组,类型为 cv::Scalar,包含最小值和最大值
InputArray mask = noArray(), // 可选掩码
Stream& stream = Stream::Null() // CUDA流用于异步执行(可选)
);
参数
- src: 输入矩阵。
- dst: 输出数组,类型为cv::Scalar,包含最小值和最大值。
- mask: 可选掩码。
- stream: CUDA流用于异步执行(可选)。
4. [同时获取最小最大值和它们的位置] cv::cuda::findMinMaxLoc
原型
cpp
void cv::cuda::findMinMaxLoc
(
InputArray src, // 输入数组
OutputArray minMaxVals, // 输出数组,包含最小值和最大值
OutputArray loc, // 输出数组,包含最小值和最大值的位置
InputArray mask = noArray(), // 可选掩码
Stream& stream = Stream::Null() // CUDA流用于异步执行(可选)
);
参数
- src: 输入矩阵。
- minMaxVals: 输出数组,包含最小值和最大值。
- loc: 输出数组,包含最小值和最大值的位置。
- mask: 可选掩码。
- stream: CUDA流用于异步执行(可选)。
代码示例
cpp
#include <iostream>
#include <opencv2/cudaarithm.hpp>
#include <opencv2/opencv.hpp>
int main()
{
// 创建测试矩阵(4x4 浮点型)
cv::Mat h_mat = ( cv::Mat_< float >( 4, 4 ) << 1, -2, 3, -4, 5, -6, 7, -8, 9, -10, 11, -12, 13, -14, 15, -16 );
// 将矩阵上传到GPU
cv::cuda::GpuMat d_mat;
d_mat.upload( h_mat );
// 方法一:同步接口获取 min/max 及其位置
double minVal, maxVal;
cv::Point minLoc, maxLoc;
cv::cuda::minMaxLoc( d_mat, &minVal, &maxVal, &minLoc, &maxLoc );
std::cout << "Min value: " << minVal << "\n";
std::cout << "Max value: " << maxVal << "\n";
std::cout << "Min location: (" << minLoc.x << ", " << minLoc.y << ")\n";
std::cout << "Max location: (" << maxLoc.x << ", " << maxLoc.y << ")\n";
// 方法二:异步接口获取 min/max 及其位置
cv::cuda::GpuMat d_minMaxVals, d_loc;
cv::cuda::findMinMax( d_mat, d_minMaxVals ); // 得到 [min, max]
cv::cuda::findMinMaxLoc( d_mat, d_minMaxVals, d_loc ); // 必须传入前一步结果!
// 下载数值
cv::Mat host_minMaxVals;
d_minMaxVals.download( host_minMaxVals );
if ( host_minMaxVals.type() != CV_32F || host_minMaxVals.total() != 2 )
{
std::cerr << "Unexpected type or size for minMaxVals!" << std::endl;
return -1;
}
const float* vals = reinterpret_cast< const float* >( host_minMaxVals.data );
std::cout << "Downloaded min value: " << vals[ 0 ] << "\n";
std::cout << "Downloaded max value: " << vals[ 1 ] << "\n";
// 下载位置
cv::Mat host_loc;
d_loc.download( host_loc );
std::cout << "loc type: " << host_loc.type() << std::endl;
std::cout << "loc total elements: " << host_loc.total() << std::endl;
if ( host_loc.type() != CV_32SC1 || host_loc.total() != 2 )
{
std::cerr << "Unexpected type or size for loc! Type: " << host_loc.type() << ", Size: " << host_loc.total() << std::endl;
return -1;
}
const int* locData = host_loc.ptr< int >();
std::cout << "Downloaded min location: (" << locData[ 0 ] << ", " << locData[ 1 ] << ")\n";
std::cout << "Downloaded max location: (" << locData[ 2 ] << ", " << locData[ 3 ] << ")\n";
return 0;
}
运行结果
bash
Min value: -16
Max value: 15
Min location: (3, 3)
Max location: (2, 3)
Downloaded min value: -16
Downloaded max value: 15
loc type: 4
loc total elements: 2
Downloaded min location: (15, 14)
Downloaded max location: (0, 0)