在OpenCv Mat中夹取数值的最有效方法是什么?

11

我有一个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);   
}

但我不确定它是否是最短的,或者split/merge是否有效率。

1个回答

1

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

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


谢谢您的评论,但我不确定如何使用“阈值”比我上面展示的“min”/“max”更有效地进行夹紧。在进一步阅读后,看起来“split”/“merge”是C++中“cvSetImageCOI”/“cvGetImageCOI”的等效物。 - Kyle McDonald
在C++接口中,“split”和“merge”对应于C接口中的“cvSplit”和“cvMerge”函数。拆分与设置COI不同-前者实际上将数据从源移动到目标,而后者仅修改图像对象头。合并也是如此。寻找避免拆分/合并的方法可能是提高性能的最佳选择。我无法保证它会更有效(你是指有效而不是有效吧?)-你最好比较不同的实现,并使用速度更快的那个。 - mpenkov
是的,肯定是指“高效”而不是“有效”。感谢您澄清cvSplit/cvMerge,我可能误解了2.3参考手册。那么,没有2.x的COI方法了吗? - Kyle McDonald
手册的C++部分似乎没有多少关于COI的参考。要么是C++ COI方式非常难懂,要么就是它不存在。您仍然可以在C++代码中使用旧的C接口(有点丑陋,但可以工作)。struct IplImagecv::Mat的底层存储是相同的,因此您可以在两者之间进行相对较小的开销转换。这将使您的代码更加丑陋,但如果使用COI而不是拆分可以完成工作,则可能值得这样做。 - mpenkov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接