在 OpenCv Mat 中钳位值的最有效方法

Posted

技术标签:

【中文标题】在 OpenCv Mat 中钳位值的最有效方法【英文标题】:Most efficient way to clamp values in an OpenCv Mat 【发布时间】:2011-09-26 09:08:08 【问题描述】:

我有一个 OpenCv Mat 将用于按像素重新映射,称为 remap,它具有 CV_32FC2 元素。

其中一些元素可能超出了重映射的允许范围。所以我需要将它们夹在Point2f(0, 0)Point2f(w, h) 之间。用 OpenCv 2.x 完成此任务的最短或最有效的方法是什么?

这里有一个解决方案:

void clamp(Mat& mat, Point2f lowerBound, Point2f upperBound) 
    vector<Mat> matc;
    split(mat, matc);
    min(max(matc[0], lowerBound.x), upperBound.x, matc[0]);
    min(max(matc[1], lowerBound.y), upperBound.y, matc[1]);
    merge(matc, mat);   

但我不确定它是否最短,或者拆分/合并是否有效。

【问题讨论】:

【参考方案1】:

尝试拆分,使用cvThreshold,然后合并。你也可以使用cvSetImageCOI 来避免分裂。我不确定阈值代码是否支持 COI。

您可能希望对这两个版本进行概要分析并比较它们的性能。我感觉它会做同样的事情。

【讨论】:

感谢您的评论,但我不确定如何使用threshold 比上面显示的min/max 更有效地进行夹紧。在阅读更多内容后,看起来split/mergecvSetImageCOI/cvGetImageCOI 的 C++ 等价物。 C++接口中的splitmerge对应C接口中的cvSplitcvMerge函数。拆分与设置 COI 不同——前者实际上将数据从源移动到目标,而后者只是修改图像对象的标题。合并也是一样。寻找避免拆分/合并的方法可能是提高性能的最佳选择。我不能真正保证它会更高效(你的意思是高效,而不是有效,对吧?)——你最好的选择可能只是比较不同的实现并使用更快的实现。 是的,绝对意味着“高效”而不是“有效”。感谢您澄清 cvSplit/cvMerge,我一定已经了解 2.3 refman。我想那时没有 2.x 的方式来做 COI? 手册的 C++ 部分中似乎没有太多对 COI 的引用。 C++ COI 方式要么真的很神秘,要么不存在。您仍然可以将旧的 C 接口与 C++ 代码一起使用(它有点难看,但它会起作用)。 struct IplImagecv::Mat 的底层存储是相同的,因此您可以在两者之间进行转换,开销相对较小。它会让你的代码更丑陋,但如果使用 COI 而不是拆分来完成工作,那么它可能是值得的。

以上是关于在 OpenCv Mat 中钳位值的最有效方法的主要内容,如果未能解决你的问题,请参考以下文章

这个函数有啥作用?与钳位值有关吗?

在YUV_420_888中将图像从Android发送到OpenCV Mat中的JNI的最有效方式

OpenCV_Mat类对象常用属性值的获取方法

在 OpenCV 中循环遍历 16 位 Mat 像素的有效方法

OpenCV:获取 Mat 值的总数

在 OpenCV 中选择图像的非矩形 ROI 的最有效方法是啥?