为什么图像二值化显示较差的结果?

时间:2016-10-11 23:02:43

标签: c#-4.0 image-processing filtering histogram threshold

enter image description here

请参阅this journal article

4.1节(预处理)的最后一段说明了 enter image description here

使用[ threshold = (mean + std dev) ]和Otsu Thresholding会得到以下结果,

enter image description here

而且,如果没有它们,我会得到以下结果,

enter image description here

因此,我有三个问题,

(1)我实现Binary Thresholding的主要问题是什么?

(2)如果Otsu Threshold确实给出了好的结果,为什么文章的作者建议使用[threshold = (mean + std dev)]?

(3)如何将double值应用为Otsu的阈值?

enter image description here

源代码

enter image description here

Here is the GitHub repository.

源代码中最相关的部分如下,

    private void thresholdButton_Click(object sender, EventArgs e)
    {
        Bitmap color = (Bitmap)this.inputImagePictureBox.Image;

        Bitmap temp = Grayscale.ToGrayscale((Bitmap)color.Clone());

        ImageStatistics imgStat = new ImageStatistics(temp);

        Histogram histogram = imgStat.Gray;

        double meanPlusStdDev = histogram.Mean + histogram.StdDev;

        OtsuThreshold otsu = new OtsuThreshold();

        int thres = otsu.getOtsuThreshold(temp);//////

        //otsu.Apply(temp, (int)meanPlusStdDev);

        otsu.Apply(temp, thres);

        thresholdedImagePictureBox.Image = temp;
    }

2 个答案:

答案 0 :(得分:2)

我只回答(2)。我还没有看到有人在全局使用mean + stdev,但在应用局部自适应阈值技术时却很常见。因此,不是为整个图像计算单个阈值,而是根据它的邻域为每个像素计算一个阈值。在本文中描述的应用程序中它会更有意义。具有局部均值(x,y)和局部stdev(x,y)的像素(x,y)的Niblack自适应阈值处理是:

mean(x,y)+ k * stdev(x,y)

其中k是可调参数。它在文档二值化中非常常用。另一个常见的是

t * mean(x,y)+ k * stdev(x,y)

您可以在其中调整本地平均值和本地stdev阈值。 stdev术语的重点是赋予边缘权重。划痕始终是高局部标准偏差的区域,因此使用与之相关的术语应该比简单的平均阈值更有效。

如果这些看起来很有趣,您还可以查看Sauvola算法,它是对Niblack算法的进一步修改。如果您想自己实现这些概念,请查看积分图像的概念。

答案 1 :(得分:2)

1)没有“问题”。您使用不同的阈值进行阈值处理,然后得到不同的结果。

2)没有找到全局阈值的通用方法,全局阈值处理可能是一个非常糟糕的解决方案。均值/ stdev方法的一个小优点是它留下了一个可调参数(stdev前面的系数),它给实现者一个(错误的)控制感。

3)我无法理解这个问题。阈值是整数,因为像素值是整数。