在opencv2 / 3中清除图像的最有效方法

时间:2016-02-19 13:46:19

标签: c++ opencv

我目前正在将旧的OpenCV C代码移植到OpenCV 2/3的C ++接口,而且我不太确定旧功能的某些等价物。很早我遇到cvZero的问题。我找到的唯一可能是通过Mat::setTo设置矩阵内容。现在,必须能够管理多通道标量和不同的数据类型,setTo遍历矩阵的所有元素并一个接一个地设置它们,而cvZero基本上执行memset。我想知道使用C ++接口的推荐方法是什么,以防我只想将图像清除为黑色。

谢谢!

1 个答案:

答案 0 :(得分:4)

yourMat = cv::Mat::zeros(yourMat.size(), yourMat.type())似乎没有分配新内存但只覆盖​​现有的Mat对象(以前分配了内存,否则.size为0)。不确定memset是否在内部使用,但是这个示例代码使.setTo版本的处理时间比使用cv::Mat::zeros的版本长50% - 但我没有评估操作的偏移量(在两个版本中应该完全相同)!

int main(int argc, char* argv[])
{
    cv::Mat input = cv::imread("C:/StackOverflow/Input/Lenna.png");

    srand(time(NULL));

    cv::Mat a = input;
    cv::Mat b = input;
    cv::imshow("original", a);

    b = cv::Mat::zeros(a.size(), a.type());

    std::vector<int> randX;
    std::vector<int> randY;
    std::vector<cv::Vec3b> randC;

    int n = 500000;

    randX.resize(n);
    randY.resize(n);
    randC.resize(n);

    for (unsigned int i = 0; i < n; ++i)
    {
        randX[i] = rand() % input.cols;
        randY[i] = rand() % input.rows;
        randC[i] = cv::Vec3b(rand()%255, rand()%255, rand()%255);
    }

    clock_t start1 = clock();
    for (unsigned int i = 0; i < randX.size(); ++i)
    {
        b.at<cv::Vec3b>(randY[i], randX[i]) = randC[i];
        b = cv::Mat::zeros(b.size(), b.type());
    }
    clock_t end1 = clock();

    clock_t start2 = clock();
    for (unsigned int i = 0; i < randX.size(); ++i)
    {
        b.at<cv::Vec3b>(randY[i], randX[i]) = randC[i];
        b.setTo( cv::Scalar(0, 0, 0));
    }
    clock_t end2 = clock();

    std::cout << "time1 = " << ( (end1 - start1) / CLOCKS_PER_SEC )  << " seconds" << std::endl;
    std::cout << "time2 = " << ((end2 - start2) / CLOCKS_PER_SEC) << " seconds" << std::endl;


    cv::imshow("a", a);
    cv::imshow("b", b);

    cv::waitKey(0);
    return 0;
}

给我输出:

time1 = 14 seconds
time2 = 21 seconds
我的机器上的

(发布模式)(没有IPP)。 以及ab的黑色图像,表示没有分配新的内存,但使用了现有的Mat内存。

int n = 250000;将生成输出

time1 = 6 seconds
time2 = 10 seconds

这不是关于memset是否在内部使用或者是否与cvZero一样快的答案,但至少你现在知道如何设置为比.setTo

更快的零