opencv中阈值的替代方案

时间:2014-02-26 05:15:18

标签: opencv image-processing computer-vision

我在Opencv中使用阈值来查找轮廓。我的输入是手形图像。有时阈值不好,所以我找不到轮廓。

我已应用以下预处理步骤
1. Grabcut

cv::grabCut(image, result,rectangle,bgModel,fgModel, 3,cv::GC_INIT_WITH_RECT);
  1. 灰度转换

    cvtColor(handMat,handMat,CV_BGR2GRAY);

  2. meadianblur

    medianBlur(handMat,handMat,MEDIAN_BLUR_K);

  3. 我使用以下代码查找阈值

    threshold( handMat, handMat, 141, 255, THRESH_BINARY||CV_THRESH_OTSU );
    

    有时我会得到好的输出,有时阈值输出不好。我附上了两个输出图像。

    除了可以找到轮廓的阈值之外还有其他方法吗?

    良好的门槛输出:

    enter image description here

    错误的阈值输出

    enter image description here

2 个答案:

答案 0 :(得分:5)

你试过adaptive threshold吗?单个阈值很少在现实生活中应用。另一个真理 - 阈值是非线性操作,因此是不稳定的。另一方面,渐变是线性的,因此如果背景是光滑和纯色,您可能希望通过跟踪渐变来找到轮廓。在光照变化或阴影期间,梯度也比阈值处理更可靠。

顺便说一下,当已经找到了90%左右的片段时,抓取,使用颜色信息来改善边界上的分割,因此它是后期处理步骤。此外,您使用矩形初始化抓取切割会使背景颜色受到很多污染。而不是矩形使用一个掩码,你可以确定手是在你的初始段深处标记为GC_FGD;在您确定背景的区域外标记为GC_BGD;标记GC_PR_FGD或者可能是其他地方的前景 - 这将由grab cut改进。总结一下 - 你的抓取初始化看起来像一个俄罗斯娃娃,有三层表示前景(灰色),可能是前景(白色)和背景(黑色)。您可以使用dilate and erode创建这些图层,请参阅下面的

enter image description here

总体而言,我的建议是首先定义您想要做的事情。您是否在任意移动背景上寻找任意物体的轮廓?如果你正在寻找手的轮廓以在相对均匀的背景上找到手指,我会: 1. use connected componentsMSER分出一只手。使用保守面具而非矩形初始化的抓取切割可能会改善结果! 2.如果这是您的目标,请使用convexity defects查找手指;

答案 1 :(得分:1)

一个问题是尝试在不对图像进行二值化的情况下查找轮廓。 如果您的输入是彩色的,您可以尝试更改颜色空间,以增强手和背景之间的差异。

Otsu尝试找到最佳阈值,您也可以尝试手动设置它,但Otsu很有用,因为如果照明发生变化,阈值将自动适应。

还有许多其他类型的二值化:Sauvola,Bradley,Niblack,Kasar ......但Otsu很简单,而且效果很好。如果您想改善二值化结果,我建议您进行预处理或后处理。