C OpenCV:迭代Mat中的像素,后者是另一个Mat的ROI | 您所在的位置:网站首页 › opencv遍历像素的方式 › C OpenCV:迭代Mat中的像素,后者是另一个Mat的ROI |
我有一个非常大的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 实验室设备网 版权所有 |