请引用this journal article .
使用 [threshold = (mean + std dev)
] 以及 Otsu 阈值给出以下结果,
.
而且,如果没有它们,我会得到以下结果,
.
因此,我有三个问题,
(1) 我实现二进制阈值的主要问题是什么?
(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;
}
最佳答案
我只会回答(2)。我还没有看到有人在全局范围内使用mean + stdev,但在应用局部自适应阈值技术时,这是很常见的。因此,您不必为整个图像计算单个阈值,而是根据其邻域为每个像素计算一个阈值。这在文章中描述的应用程序中更有意义。具有局部平均值(x,y)和局部stdev(x,y)的像素(x,y)的Niblack自适应阈值是:
均值(x,y) + k * 标准差(x,y)
其中 k 是一个可调参数。它在文档二值化中非常常用。另一种常见的是
t * 均值(x,y) + k * 标准差(x,y)
您可以在其中调整本地均值和本地标准差阈值。 stdev 项的要点是赋予边缘权重。划痕始终是局部标准偏差较高的区域,因此与之相关的术语应该比简单的均值阈值更有效。
如果您觉得有趣,您还可以查看 Sauvola 算法,它是 Niblack 算法的进一步修改。如果您想自己实现这些,请查看积分图像的概念。
关于c#-4.0 - 为什么图像二值化显示的结果较差?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39988081/