我正在使用OpenCV的cv::findContours
函数来提取二进制图像中的轮廓,特别是,我正在提取轮廓的层次结构(使用CV_RETR_CCOMP
标志)。在我对这些轮廓进行进一步处理的某些时候,我需要依赖这些轮廓的一致的顶点方向(即逆时针与顺时针方向)。
当然我可以使用轮廓区域的符号(由cv::contourArea(..., true)
计算)来确定方向,但我想知道是否有必要(除此之外,它甚至不适用于轮廓区域为0,即源图像中的细线)或cv::findContours
已经保证生成的轮廓的方向一致。我确实检查了一些生成的轮廓,cv::contourArea
确实似乎返回外轮廓的负值和内轮廓的正值。但是,我在OpenCV文档中找不到任何实际的保证。
那么, 特别保证 cv::findContours
返回的轮廓始终具有一致的方向?这是否记录在任何地方?或者它是否因版本而异(我的情况是2.4.5)?实际的paper on the algorithm referenced in the documentation是否已经说过这个了?或者,对OpenCV的实际实现有一点洞察力的人可以比界面文档更多地说明这一点吗?
答案 0 :(得分:7)
从cv:findContours
返回的轮廓应该具有一致的方向。外轮廓应逆时针方向,内轮廓顺时针方向。这直接来自Suzuki's and Abe's paper附录1中描述的算法。
从左上角到右下角逐行扫描图像。当找到属于边界的像素时,边界之后是以逆时针顺序查看第一像素的邻居(参见算法中的步骤3.3),直到找到非背景像素。这将添加到轮廓中,并从此像素继续搜索。
重要的是,在第一次迭代中,首先查看的邻居取决于它是内边界还是外边界。在外边界的情况下,首先访问右手边界;在内边界的情况下,它是左手邻居。在下一个搜索步骤中,搜索从最后访问的像素开始。
由于从左上角到右下角的扫描晃动,在检测到外边界时,确保左边的所有相邻像素和边界像素的顶部是背景像素。对于内边框,它恰好相反,左边和顶边的所有邻居都是非背景像素。
结合访问相邻像素的不同起始位置,可以获得轮廓的可预测方向。
此算法在icvFetchContour
function中实现,documentation for cv::findContours
由cv:findContour
内部使用。从那里可以清楚地看到,像素按照它们被访问的顺序被添加到轮廓多边形中。
由于{{3}}明确表示他们实施了Suzuki等人的算法。并且在本文中,访问像素的方向和顺序是明确定义的,我认为可以假设方向是有保证的。
答案 1 :(得分:3)