OpenCV如何处理Mat作为指针来加速代码

OpenCV How to deal with Mat as pointer to speed up the code?

本文关键字:指针 代码 加速 Mat 何处理 处理 OpenCV      更新时间:2023-10-16

我试图将指针与cv::Mat一起使用,但我不太理解。

当我尝试这个:

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat src = imread("image.png");
Mat img;
Mat temp;
img = Mat(src.rows, src.cols, CV_8UC1, cv::Scalar(0));
temp = Mat(src.rows, src.cols, CV_8UC1, cv::Scalar(0));
temp = img(Range(10, 20), Range(40, 60));
temp.setTo(255);
imshow("img", img);
waitKey();
return 0;
}

它有效,没有问题。然而,当我将其更改为:时

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat src = imread("image.png");
Mat* img;
Mat* temp;
*img = Mat(src.rows, src.cols, CV_8UC1, cv::Scalar(0));
*temp = Mat(src.rows, src.cols, CV_8UC1, cv::Scalar(0));
temp = img(Range(10, 20), Range(40, 60));
temp.setTo(255);
imshow("img", *img);
waitKey();
return 0;
}

我得到这个错误:

明显调用的括号前的

表达式必须具有(指针指向-(功能类型

temp = img(Range(10, 20), Range(40, 60));

错误:

表达式必须具有类类型

temp.setTo(255);

Mat作为加速代码的指针处理的一般规则是什么?

例如,我知道在函数自变量中,我们将&用于输入Mats,将*用于输出Mats。但是,如何在函数中定义和使用Mats有一个通用规则吗?

请告诉我这个代码是否还有其他问题,因为我是一个初学者。非常感谢。

在您发布的示例中,使用指针没有任何好处。在您的指针示例中,存在许多问题。

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat src = imread("image.png");
Mat* img; // Uninitialized pointer; points to random memory
Mat* temp; // Uninitialized pointer; points to random memory
// Undefined behavior: dereferencing an uninitialized pointer
// You are basically trying to treat some random piece of memory
// as a cv::Mat and trying to assign another cv::Mat to it.
*img = Mat(src.rows, src.cols, CV_8UC1, cv::Scalar(0)); 
*temp = Mat(src.rows, src.cols, CV_8UC1, cv::Scalar(0));
// Syntax error: img has type Mat*; you could call the
// Mat Mat::operator()( Range _rowRange, Range _colRange ) const
// Like this:
// *temp = img->operator()(Range(10, 20), Range(40, 60));
// or like this:
// *temp = (*img)(Range(10, 20), Range(40, 60));
// that would work if img and temp were to point to valid cv::Mats
temp = img(Range(10, 20), Range(40, 60));
// Syntax error temp has type Mat*
//  to access a pointers members use -> instead of .
temp.setTo(255);
imshow("img", *img);
waitKey();
return 0;
}

通常,复制cv::Mat是一种低成本操作,因为它不会创建整个缓冲区的副本,而是增加引用计数,并复制一些如何解释该缓冲区的信息。在典型的硬件上,你可以预计这最多需要几十纳秒的数量级。简单的图像处理操作很容易花费一百万倍的时间。

很少有理由用指针指向简历::Mat。如果切换到指针,这样做是因为它更有意义,而不是为了提高性能。通过(const(引用而不是通过值传递mats可能仍然是正确的默认选择。

具有cv::Mat指针的一个用例可能是可选的out参数:

void mayBeNull(cv::Mat* matPointer = nullptr)
{
if(matPointer!=nullptr)
{
// assign something to *matPointer
}
else
{
// do not use matPointer
// the caller does not care about our outparam
}
}