C OpenCV:迭代Mat中的像素,后者是另一个Mat的ROI 您所在的位置:网站首页 opencv遍历像素的方式 C OpenCV:迭代Mat中的像素,后者是另一个Mat的ROI

C OpenCV:迭代Mat中的像素,后者是另一个Mat的ROI

2023-04-24 21:13| 来源: 网络整理| 查看: 265

我有一个非常大的Mat,实际上是另一个Mat的ROI(由otherMat(cv :: Rect(x,y,w,h)获得))。我想遍历Mat的所有像素,进行一些像素计算,然后使用指针将结果写入另一个Mat。

到目前为止,遍历所有像素(包括ROI外部的像素)都可以正常工作,但是我想知道跳过ROI外部像素的最快方法是什么。我想要尽可能少的缓存未命中,并且我也不想效率低下的分支预测。最好的方法是什么?

编辑:我对获得感兴趣的特定区域的子矩阵不感兴趣。我有兴趣以最大效率的方式逐个指针遍历像素,而无需访问子矩阵区域之外的数据。

相关讨论 可能重复的stackoverflow.com/questions/16621983/… OpenCV C接口如何管理ROI的可能重复项 您可以将此ROI复制到新的Mat,以便它是连续的,我认为没有其他方法可以避免出现缓存和分支预测遗漏的情况-尝试一下并测量哪个更快 不过,这似乎很像是过早/微优化,您是否对应用程序进行了概要分析并在那里找到了瓶颈? 当然,这是一个很小的优化,但是由于我在移动设备上工作,因此许多小的改进都可以带来很大的不同。无论如何,我对总体上最佳的解决方案感兴趣,而与实际运行时的优势无关。

只需使用一个子矩阵:

12345cv::Mat largeMat cv::Rect roi(yourROI); cv::Mat submatrix = largeMat(roi); // now iterate over all the pixels of submatrix

您将在每一行的末尾出现缓存未命中

这是实际的代码示例,该示例显示了子垫外的像素被跳过(您将在每行的末尾看到一个额外的缓存未命中,但这应该是全部)。

12345678910111213141516171819int main(int argc, char* argv[]) {     cv::Mat input = cv::imread("C:/StackOverflow/Input/Lenna.png");     cv::Rect roi(128, 128, 256, 256);     cv::Mat submat = input(roi);     cv::MatIterator_ it; // = src_it.begin();     for (it = submat.begin(); it != submat.end(); ++it)     {         (*it)[0] = 0;         (*it)[1] = 0;     }     cv::imshow("input", input);     cv::imwrite("C:/StackOverflow/Output/submatIter.png", input);     cv::waitKey(0);     return 0; }

给出以下结果:

如果您想更快一点,可以使用行指针:http://docs.opencv.org/2.4/doc/tutorials/core/how_to_scan_images/how_to_scan_images.html

请注意,他们在链接中比较了调试模式的运行时速度,这就是为什么随机访问如此缓慢的原因。在发布模式下,它应该比迭代器版本快(或更快)。 但是这里是row-Ptr版本(可用来计算每个像素访问的行偏移量),它给出的结果相同,应该是最快的方法(如果openCV的LUT函数不能用于您的任务):

123456789101112131415161718192021222324int main(int argc, char* argv[]) {     cv::Mat input = cv::imread("C:/StackOverflow/Input/Lenna.png");     cv::Rect roi(128, 128, 256, 256);     cv::Mat submat = input(roi);     cv::Vec3b * currentRow;     for (int j = 0; j


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有