[英]Most efficient way to clear an image in opencv2/3
我目前正在將舊的OpenCV C代碼移植到OpenCV 2/3的C ++接口,我不太確定舊功能的等價物。 很早我遇到了cvZero
的問題。 我找到的唯一可能是通過Mat::setTo
設置矩陣內容。 現在,必須能夠管理多通道標量和不同的數據類型, setTo
迭代遍歷矩陣的所有元素並一個接一個地設置它們,而cvZero
基本上做了一個memset
。 我想知道使用C ++接口的推薦方法是什么,以防我只想清除我的圖像黑色。
謝謝!
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)。 和兩個黑色圖像, a
和b
指示沒有新的存儲器被分配,但是使用現有的墊存儲器。
int n = 250000;
會產生輸出
time1 = 6 seconds
time2 = 10 seconds
這不是關於memset是否在內部使用或者是否與cvZero一樣快的答案,但至少你現在知道如何設置為比.setTo
更快的零
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.