我试图做一个快速的图像阈值功能。目前我正在做的是:
void threshold(const cv::Mat &input, cv::Mat &output, uchar threshold) {
int rows = input.rows;
int cols = input.cols;
// cv::Mat for result
output.create(rows, cols, CV_8U);
if(input.isContinuous()) { //we have to make sure that we are dealing with a continues memory chunk
const uchar* p;
for (int r = 0; r < rows; ++r) {
p = input.ptr<uchar>(r);
for (int c = 0; c < cols; ++c) {
if(p[c] >= threshold)
//how to access output faster??
output.at<uchar>(r,c) = 255;
else
output.at<uchar>(r,c) = 0;
}
}
}
}
我知道
at()
函数的运行速度很慢。我如何才能更快地设置输出,或者换句话说,如何将我从输入中获得的指针与输出相关联? 最佳答案
您正在考虑 at
,因为C++标准库为几个容器记录了它,执行范围检查并抛出异常,但是这不是标准库,而是OpenCV。
根据cv::Mat::at文档:
因此,您可能会想到没有范围检查。
比较源代码中的 cv::Mat::at
和 cv::Mat::ptr
,我们可以看到它们几乎相同。
所以cv::Mat::ptr<>(row)和
return (_Tp*)(data + step.p[0] * y);
虽然cv::Mat::at<>(row, column)的价格昂贵:
return ((_Tp*)(data + step.p[0] * i0))[i1];
您可能希望直接采用
cv::Mat::ptr
而不是在每一列上都调用 cv::Mat::at
以避免进一步重复data + step.p[0] * i0
操作,而自己做[i1]
。所以你会做:
/* output.create and stuff */
const uchar* p, o;
for (int r = 0; r < rows; ++r) {
p = input.ptr<uchar>(r);
o = output.ptr<uchar>(r); // <-----
for (int c = 0; c < cols; ++c) {
if(p[c] >= threshold)
o[c] = 255;
else
o[c] = 0;
}
}
附带说明一下,您在此处不应该也不应该检查
cv::Mat::isContinuous
,间隙是从一行到另一行,您将指针指向单行,因此您不需要处理矩阵间隙。关于c++ - 在C++中使用指针加速对数组的访问,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30247418/