[C++] opencv - minMaxLoc函数介绍和使用场景

27 篇文章 2 订阅

OpenCV是一个开源的计算机视觉库,提供了许多图像处理和计算机视觉方面的功能。其中,minMaxLoc函数是OpenCV中非常重要的一个函数,用于查找图像中的最大值和最小值及其位置。本文将介绍minMaxLoc函数的相关知识,包括函数的介绍、函数原型和参数说明、函数使用的场景、完整代码实例以及总结等。

一、函数的介绍

minMaxLoc函数用于在一幅图像中查找最大值和最小值及其位置。该函数可以应用于灰度图像和彩色图像,支持多通道图像。使用该函数可以方便地进行图像分割、特征提取等任务。

二、函数原型和参数说明

下面是minMaxLoc函数的原型和参数说明:

double cv::minMaxLoc(InputArray src, OutputArray minVal, OutputArray maxVal, OutputArray minLoc, OutputArray maxLoc, InputArray mask = noArray());

其中,各个参数的含义如下:

  • src:输入图像或矩阵,可以是单通道、多通道或彩色图像。
  • minVal:输出参数,指向一个double类型的指针,用于存储计算得到的最小值。
  • maxVal:输出参数,指向一个double类型的指针,用于存储计算得到的最大值。如果不提供此参数,则默认为0。
  • minLoc:输出参数,指向一个Point类型的指针,用于存储计算得到的最小值的位置。如果不提供此参数,则默认为0。
  • maxLoc:输出参数,指向一个Point类型的指针,用于存储计算得到的最大值的位置。如果不提供此参数,则默认为0。
  • mask:可选参数,输入图像或矩阵,用于指定感兴趣区域。只有位于mask内的像素才会被计算最小值和最大值。如果不提供此参数,则默认为noArray()。

三、函数使用的场景

minMaxLoc函数可以应用于以下场景:

  1. 图像分割:在图像分割中,需要找到图像中的前景和背景,可以使用minMaxLoc函数来确定前景和背景的阈值。
  2. 目标检测:在目标检测中,需要找到目标的位置,可以使用minMaxLoc函数来确定目标的边界框。
  3. 特征提取:在特征提取中,需要找到图像中的特征点,可以使用minMaxLoc函数来确定特征点的位置。

四、代码实例

下面是一个使用minMaxLoc函数查找图像中最大值和最小值及其位置的完整代码实例:

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
    // 读取图像
    Mat img = imread("test.jpg");
    if (img.empty())
    {
        cout << "Failed to read image!" << endl;
        return -1;
    }

    // 初始化输出参数
    double minVal, maxVal;
    Point minLoc, maxLoc;

    // 查找最大值和最小值及其位置
    minMaxLoc(img, &minVal, &maxVal, &minLoc, &maxLoc);

    // 输出结果
    cout << "Min value: " << minVal << endl;
    cout << "Max value: " << maxVal << endl;
    cout << "Min location: (" << minLoc.x << ", " << minLoc.y << ")" << endl;
    cout << "Max location: (" << maxLoc.x << ", " << maxLoc.y << ")" << endl;

    return 0;
}

下面是一个YoloV8推理程序中使用minMaxLoc函数查找某张图像在coco数据集的80个分类(1维数组 1x80)中哪个类别的概率最大值及其分类Id的部分代码实例:

std::vector<Detection> Yolov8::detect(const cv::Mat& rawImg, cv::dnn::Net& net) {
	clock_t t1 = clock();
	// transform raw image with 3 channels
    cv::Mat squareRawImg = tranformToSquare(rawImg);
	cv::Mat blob;
    // create 4-dimensional mat (1 ,3 , 640  , 640) which means (batch size + channels + height + width)
	cv::dnn::blobFromImage(squareRawImg, blob, 1.0 / 255.0, cv::Size(netWidth, netHeight), cv::Scalar(), true, false);
	
	clock_t t2 = clock();
	// detect the object and get the outputs
	net.setInput(blob);
	std::vector<cv::Mat> outputs;
	net.forward(outputs, net.getUnconnectedOutLayersNames());
    
	clock_t t3 = clock();
	// yolov8 has an output of shape (1, 84, 8400), 84=(box[x,y,w,h] + Num of classes),8400=the detection count
	cv::Mat outputMat = outputs[0];
	int rows = outputMat.size[2];
	int dimensions = outputMat.size[1];

	// change mat from (1, 84, 8400) to (84, 8400) 
	outputMat = outputMat.reshape(1, dimensions);  
	// change mat from (84, 8400) to (8400, 84) 
	cv::transpose(outputMat, outputMat);
 
	float* data = (float*)outputMat.data;
	float xFactor = (float)squareRawImg.cols / netWidth;
	float yFactor = (float)squareRawImg.rows / netHeight;
 
	std::vector<int> classIds;
	std::vector<float> confidences;
	std::vector<cv::Rect> boxes;
    
	// iterate the 8400 detections and keep the result >= confidence thresold.
	for (int i = 0; i < rows; ++i)
	{
		// get the score for every class and find out the class with highest score
		cv::Mat scores(1, classes.size(), CV_32FC1, data + 4); 
		cv::Point classId;
		double maxClassScore;
		cv::minMaxLoc(scores, 0, &maxClassScore, 0, &classId);

		if (maxClassScore >= confidenceThreshold)
		{
			confidences.push_back(maxClassScore);
			classIds.push_back(classId.x);
 
			float x = data[0]; // the center x for detection box
			float y = data[1]; // the center y for detection box
			float w = data[2]; // the width for detection box
			float h = data[3]; // the height for detection box
 
			int left = int((x - 0.5 * w) * xFactor);
			int top = int((y - 0.5 * h) * yFactor);
 
			int width = int(w * xFactor);
			int height = int(h * yFactor);
 
			boxes.push_back(cv::Rect(left, top, width, height));
		}
		data += dimensions;
	}
    ...
}

五、总结

本文介绍了OpenCV中的minMaxLoc函数,包括函数的介绍、函数原型和参数说明、函数使用的场景、完整代码实例以及总结等。minMaxLoc函数是OpenCV中非常重要的一个函数,可以方便地进行图像分割、特征提取等任务。在实际应用中,我们可以根据具体需求选择不同的颜色空间转换码,以实现不同的图像处理任务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老狼IT工作室

你的鼓励将是我创作的最大动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值