OpenCV 如何处理 Mat 作为指针来加速代码?
OpenCV How to deal with Mat as pointer to speed up the code?
我正在尝试将指针与 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;
}
我收到这个错误:
expression preceding parentheses of apparent call must have
(pointer-to-) function type
在
temp = img(Range(10, 20), Range(40, 60));
和错误:
expression must have class type
在
temp.setTo(255);
处理 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 是一种低成本操作,因为它不会创建整个缓冲区的副本,而只是增加引用计数并复制一些如何解释该缓冲区的信息。在典型的硬件上,您可以预期最多需要几十纳秒。简单的图像处理操作很容易花费一百万倍的时间。
很少有理由指向 cv::Mat。如果您切换到指针,那么这样做是因为它更有意义,而不是为了提高性能。通过(const)引用而不是值传递你的垫子可能仍然是正确的默认选择。
具有 cv::Mat 指针的一个用例可能是一个可选的输出参数:
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
}
}
我正在尝试将指针与 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;
}
我收到这个错误:
expression preceding parentheses of apparent call must have (pointer-to-) function type
在
temp = img(Range(10, 20), Range(40, 60));
和错误:
expression must have class type
在
temp.setTo(255);
处理 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 是一种低成本操作,因为它不会创建整个缓冲区的副本,而只是增加引用计数并复制一些如何解释该缓冲区的信息。在典型的硬件上,您可以预期最多需要几十纳秒。简单的图像处理操作很容易花费一百万倍的时间。
很少有理由指向 cv::Mat。如果您切换到指针,那么这样做是因为它更有意义,而不是为了提高性能。通过(const)引用而不是值传递你的垫子可能仍然是正确的默认选择。
具有 cv::Mat 指针的一个用例可能是一个可选的输出参数:
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
}
}