1、基于谷底最小值的阈值
这个方法适用于通过有限的迭代次数,平滑后能得到双峰的图像,让双峰的谷底成为阈值。当执行完基于谷底最小值的阈值操作的时候,改变了直方图信息,使之成为处理过后的直方图信息,这时候显示Doc里的数据没有问题,可是在直方图类里画图的时候却出现了这个错误。问题解决了,出现的原因是在不恰当的地方获取了数据。
A location is considered to have valley bottom flatness at a given scale if it is sufficiently low and flat at that scale and is sufficiently flat (but not necessarily low) at all finer scales. The different index values correspond to different resolutions and different slope thresholds.
(1) 描述:
此方法实用于具有明显双峰直方图的图像,其寻找双峰的谷底作为阈值,但是该方法不一定能获得阈值,对于那些具有平坦的直方图或单峰图像,该方法不合适。
(2) 实现过程:
该函数的实现是一个迭代的过程,每次处理前对直方图数据进行判断,看其是否已经是一个双峰的直方图,如果不是,则对直方图数据进行半径为1(窗口大小为3)的平滑,如果迭代了一定的数量比如1000次后仍未获得一个双峰的直方图,则函数执行失败,如成功获得,则最终阈值取两个双峰之间的谷底值作为阈值。
注意在编码过程中,平滑的处理需要当前像素之前的信息,因此需要对平滑前的数据进行一个备份。另外,首数据类型精度限制,不应用整形的直方图数据,必须转换为浮点类型数据来进行处理,否则得不到正确的结果。
2、基于谷底最小值的阈值的源程序
二值算法综述请阅读:
C#,图像二值化(01)——二值化算法综述与二十三种算法目录https://blog.csdn.net/beijinghorn/article/details/128425225?spm=1001.2014.3001.5502
支持函数请阅读:
C#,图像二值化(02)——用于图像二值化处理的一些基本图像处理函数之C#源代码https://blog.csdn.net/beijinghorn/article/details/128425984?spm=1001.2014.3001.5502
using System;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Collections;
using System.Collections.Generic;
using System.Drawing.Imaging;
namespace Legalsoft.Truffer.ImageTools
{
public static partial class BinarizationHelper
{
#region 灰度图像二值化 全局算法 谷底最小值的阈值
/// <summary>
/// 基于谷底最小值的阈值
/// </summary>
/// <param name="histogram"></param>
/// <returns></returns>
public static int Valley_Bottom_Threshold(int[] histogram)
{
double[] HistGramC = Histogram_To_Float(histogram);
double[] HistGramCC = Histogram_To_Float(histogram);
int Iter = 0;
while (Is_Dimodal_Histogram(HistGramCC) == false)
{
HistGramCC[0] = (HistGramC[0] + HistGramC[0] + HistGramC[1]) / 3;
for (int i = 1; i < 255; i++)
{
HistGramCC[i] = (HistGramC[i - 1] + HistGramC[i] + HistGramC[i + 1]) / 3;
}
HistGramCC[255] = (HistGramC[254] + HistGramC[255] + HistGramC[255]) / 3;
System.Buffer.BlockCopy(HistGramCC, 0, HistGramC, 0, 256 * sizeof(double));
Iter++;
if (Iter >= 1000)
{
return -1;
}
}
bool Peakfound = false;
for (int i = 1; i < 255; i++)
{
if (HistGramCC[i - 1] < HistGramCC[i] && HistGramCC[i + 1] < HistGramCC[i])
{
Peakfound = true;
}
if (Peakfound == true && HistGramCC[i - 1] >= HistGramCC[i] && HistGramCC[i + 1] >= HistGramCC[i])
{
return (i - 1);
}
}
return -1;
}
/// <summary>
/// 检测直方图是否为双峰的
/// </summary>
/// <param name="histogram"></param>
/// <returns></returns>
private static bool Is_Dimodal_Histogram(double[] histogram)
{
int count = 0;
for (int i = 1; i < 255; i++)
{
if (histogram[i - 1] < histogram[i] && histogram[i + 1] < histogram[i])
{
count++;
if (count > 2)
{
return false;
}
}
}
return (count == 2);
}
public static void Valley_Bottom_Algorithm(byte[,] data)
{
int[] histogram = Gray_Histogram(data);
int threshold = Valley_Bottom_Threshold(histogram);
Threshold_Algorithm(data, threshold);
}
#endregion
}
}
3、基于谷底最小值的阈值的计算结果
POWER BY TRUFFER.CN