2013-06-21 43 views
9

有谁知道Opencv是否提供了一个函数来检查一个cv :: Point是否在cv :: Mat内?检查一个cv :: Point是否在一个cv :: Mat内

基本上我做:

int x = (current.x - offset); 
int y = current.y; 
if (x >= 0 && y >= 0 && x < mat.cols && y < mat.rows) && ((int)mat.at<uchar>(y, x) == 0)){ 
     return cv::Point(x, y); 
    } 
} 

我想知道如果有什么快?或者如果这样做不好呢?

回答

19

可以构造尺寸的cv::Rect作为cv::Mat和使用其方法:

cv::Rect rect(cv::Point(), mat.size()); 
cv::Point p(x, y); 

if (rect.contains(p) && mat.at<uchar>(y, x) == 0) 
{ 
    return p; 
} 

或者,您可以捕捉异常在at()如果指数超出范围:

UPD:正如@Antonio在评论中提到的那样,以下工作只在调试模式下工作,因为“For the sake of higher performance, the index range checks are only performed in the Debug configuration”,这有点令人惊讶,与std::vector::at()的工作方式不同。

try 
{ 
    if (mat.at<uchar>(y, x) == 0) 
    { 
    return cv::Point(x, y); 
    } 
} 
catch (cv::Exception& e) 
{ 
} 

但是,请注意由例外引起的潜在性能损失。如果这个语句是在循环中执行,或者只是经常执行,则不应该使用后一种方法。或者如果它是正常的而不是特殊情况。

+0

就像你说的这是一个循环过程,这就是为什么我正在寻找最佳实践。你不觉得创建cv :: Rect有点沉重吗? – Poko

+1

我假设你对相同的图像做了几次检查,因此应该创建一个单一的矩形。如果不是,它可能比你的初始样本稍慢。如果你想要比4个简单的就地检查更有效的东西,需要更多的上下文。在这种情况下,由CPU完成分支预测和推测。 – Mikhail

+3

@Mikhail只有当OpenCV以调试模式构建时,'at'方法才会抛出范围异常。 “[为了提高性能,索引范围检查仅在Debug配置中执行](http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-at)” – Antonio