使用[ threshold = (mean + std dev)
]和Otsu Thresholding会得到以下结果,
而且,如果没有它们,我会得到以下结果,
因此,我有三个问题,
(1)我实现Binary Thresholding的主要问题是什么?
(2)如果Otsu Threshold确实给出了好的结果,为什么文章的作者建议使用[threshold = (mean + std dev)
]?
(3)如何将double
值应用为Otsu的阈值?
源代码
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;
}
答案 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)我无法理解这个问题。阈值是整数,因为像素值是整数。