我试图做一个快速的图像阈值功能。目前我正在做的是:

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/

10-13 04:41