对于灰度分布直方图有两个峰值的图像,大津法求得的T近似等于两个峰值之间的低谷。
它由大津于1979年提出,被认为是图像分割中阈值选取的最佳算法,计算简单,不受图像亮度和对比度的影响,因此在数字图像处理上得到了广泛的应用。
在白内障眼科图像处理中,也尝试了大津法。其流程为:
(1)统一图像大小;(2)利用最大类间阈值进行分割;(3)进行中值滤波;(4)构造圆形元素;(5)膨胀处理;(6)填充空洞;(7)删除小面积对象;(8)删除红黄色杂质;(9)剪切感兴趣的部分
首先将每一张图片的格式,大小进行统一,我们采用了基于双线性插值的方法进行大小转换。然后根据最大类间方差法求出整张图片的最佳阈值。随后对该标记矩阵进行中值滤波,使得被前景包围的背景区域重新被填充,避免分割到的前景中的区域被掏空。接下来进行圆形元素的构造,根据已有的前景区域,给定半径和周期线性元素结构去和给定的前景区域去近似。满足条件则可以构建出完整的圆形结构,最大可能的保持晶状体的形状。接下来对标记矩阵进行膨胀处理,通过膨胀可以使得图像中的小孔和边缘凹陷被填充。如果此时前景区域仍有空洞,则用填充函数将二值图像中的空洞填充掉。将小面积对象删除,避免未来对白内障区域的识别产生噪声和干扰。接下来从前景整个黑白相间的内容中除去红色和近似黄色的部分。根据RGB三原色的分布特征,取出剩余的红黄色杂质。处理效果如下:
由于存在被掏空的情况,因此结合了中值滤波和填充膨胀等操作。掏空情况见下图:
可见这种算法将感兴趣区域掏空了,由于被掏空区域不是闭合区域,因此中值滤波和膨胀等操作都无法将原区域回复,最终选择了canng算子和Hough变换相结合的算法。
在病理图像的处理中,为了得到病理区域,也使用该方法从病理区域进行裁剪。得到组织掩码。
病理图像细节如下图。
根据裁剪到的图像,集合医生标注,通过卷积神经网络进行识别。
盲猜是图像二值化处理的问题。
首先说结论:otsu法和threshold并不是一类东西,没法说有什么区别。otsu法是得出threshold的一个算法。
一个灰度图像,每个像素的灰度值都是一个字节,8位,也就是0~255。数越大颜色越浅,越小颜色越深,0是黑色,255是白色。
二值化图像也就是只有黑和白两种颜色,一般情况下0是黑,1是白。
将灰度图进行二值化处理时也就需要一个阈值,也就是threshold。小于这个阈值的数为0,这个点为黑色;大于这个阈值的数为1,这个点为白色。
所以图像二值化最根本的问题就在于怎么去选择这个阈值。
最简单的办法就是设定一个固定值,这是运算速度最快也是最弱智的方法。显然这种方法对环境光的要求比较高,如果整体环境的明暗发生变化,那么对设定的阈值也要重新整定。
所以需要找到一种能够自动计算出阈值的算法。这种算法有很多,OTSU法是其中用的比较多的一个方法。
OTSU法,中文叫大津法,是由日本学者大津展之提出的,因此以他的名字命名。大津法的根本思想是,首先通过聚类的方法将图像的灰度值分为前景和背景两类,再穷举所有像素点的灰度值,并计算出一个阈值使得类间方差最大,这样这个阈值就是一个理想的二值化阈值。大津法能够很好的适应图像的明暗度和对比度的变化。
大津法的具体算法可以参考这篇文章:网页链接
[csharp] using System namespace Splash Imaging { /// <summary> /// 图像处理 大津法二值化阈值计算方法 /// </summary> public static partial class Binarize { /// <summary> /// 大津法计算阈值 /// </summary> /// <param name= grayArray >灰度数组</param> /// <returns>二值化阈值</returns> public static Int OtsuThreshold(Byte[ ] grayArray) { // 建立统计直方图 Int [] Histogram = new Int [ ] Array Clear(Histogram ) // 初始化 foreach (Byte b in grayArray) { Histogram[b]++ // 统计直方图 } // 总的质量矩和图像点数 Int SumC = grayArray Length // 总的图像点数 Double SumU = // 双精度避免方差运算中数据溢出 for (Int i = i <i++) { SumU += i * Histogram[i] // 总的质量矩 } // 灰度区间 Int MinGrayLevel = Array FindIndex(Histogram NonZero) // 最小灰度值 Int MaxGrayLevel = Array FindLastIndex(Histogram NonZero) // 最大灰度值 // 计算最大类间方差 Int Threshold = MinGrayLevel Double MaxVariance = // 初始最大方差 Double U = // 初始目标质量矩 Int C = // 初始目标点数 for (Int i = MinGrayLeveli <MaxGrayLeveli++) { if (Histogram[i] == ) continue // 目标的质量矩和点数 U += i * Histogram[i] C += Histogram[i] // 计算目标和背景的类间方差 Double Diference = U * SumC SumU * C Double Variance = Diference * Diference / C / (SumC C ) // 方差 if (Variance >MaxVariance) { MaxVariance = Variance Threshold = i } } // 返回类间方差最大阈值 return Threshold } /// <summary> /// 检测非零值 /// </summary> /// <param name= value >要检测的数值</param> /// <returns> /// true:非零 /// false:零 /// </returns> private static Boolean NonZero(Int value) { return (value != ) ? true : false } } } lishixinzhi/Article/program/net/201311/13006
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)