简体   繁体   English

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

[英]Most efficient way to clear an image in opencv2/3

I'm currently porting my old OpenCV C code to the C++ interface of OpenCV 2/3 and I'm not quite sure about some equivalents of old functions. 我目前正在将旧的OpenCV C代码移植到OpenCV 2/3的C ++接口,我不太确定旧功能的等价物。 Pretty early I ran into an issue with cvZero . 很早我遇到了cvZero的问题。 The only possibility I found was to set the matrix content via Mat::setTo . 我找到的唯一可能是通过Mat::setTo设置矩阵内容。 Now, having to be able to manage multi-channel scalars and different data types, setTo iterates through all elements of the matrix and sets them one after another while cvZero basically did a memset . 现在,必须能够管理多通道标量和不同的数据类型, setTo迭代遍历矩阵的所有元素并一个接一个地设置它们,而cvZero基本上做了一个memset I am wondering what would be the recommended way for using the C++ interface, in case I just want to clear my image black. 我想知道使用C ++接口的推荐方法是什么,以防我只想清除我的图像黑色。

Thanks! 谢谢!

yourMat = cv::Mat::zeros(yourMat.size(), yourMat.type()) does not seem to allocate new memory but only overwrites the existing Mat object (memory was previously allocated, otherwise .size is 0). yourMat = cv::Mat::zeros(yourMat.size(), yourMat.type())似乎没有分配新内存但只覆盖​​现有的Mat对象(以前分配了内存,否则.size为0)。 Not sure whether memset is used internally, but this sample code gives 50% longer processing time for the version with .setTo compared to the version with cv::Mat::zeros - but I didn't evaluate the offset from the manipulation (which should be quite identical in both versions)! 不确定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;
}

gives me output: 给我输出:

time1 = 14 seconds
time2 = 21 seconds

on my machine (Release mode) (no IPP). 在我的机器上(发布模式)(没有IPP)。 and a black image for both, a and b which indicates that no new memory was allocated, but the existing Mat memory was used. 和两个黑色图像, ab指示没有新的存储器被分配,但是使用现有的垫存储器。

int n = 250000; will produce output 会产生输出

time1 = 6 seconds
time2 = 10 seconds

This is no answer about whether or not memset is used internally or whether or not it is as fast as cvZero, but at least you know now how to set to zero faster than .setTo 这不是关于memset是否在内部使用或者是否与cvZero一样快的答案,但至少你现在知道如何设置为比.setTo更快的零

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM