当前位置: 首页 > news >正文

图像二值化阈值调整——Triangle算法,Maxentropy方法

一. Triangle方法

算法描述:三角法求分割阈值最早见于Zack的论文《Automatic measurement of sister chromatid exchange frequency》主要是用于染色体的研究,该方法是使用直方图数据,基于纯几何方法来寻找最佳阈值,它的成立条件是假设直方图最大波峰在靠近最亮的一侧,然后通过三角形求得最大直线距离,根据最大直线距离对应的直方图灰度等级即为分割阈值,图示如下:

三角几何化的过程。首先找到直方图中灰度值最高的一点并判别亮暗,然后找到最左边点,两点连接一条直线,求直方图上离直线最远的点,设置该点的灰度值为阈值。

有时候最大波峰对应位置不在直方图最亮一侧,而在暗的一侧,这样就需要翻转直方图,翻转之后求得值,用255减去即得到为阈值T。扩展情况的直方图表示如下:

算法特点:适用于单峰。这点和OTSU算法有很大区别,OTSU适用于双峰。

cv2中有三角分割的算法,直接使用即可。

import cv2
import matplotlib.pylab as pltdef main():img = cv2.imread('6.jpg', 0)ret, thresh1 = cv2.threshold(img, 0, 255, cv2.THRESH_TRIANGLE)print(ret)  # 结果是151.0titles = ['Original Image', 'After Binarization']images = [img, thresh1]for i in range(2):plt.subplot(1, 2, i + 1)plt.imshow(images[i], 'gray')plt.title(titles[i])plt.xticks([])plt.yticks([])plt.show()main()

二. Maxentropy方法

最大熵阈值分割法和OTSU算法类似,假设将图像分为背景和前景两个部分。熵代表信息量,图像信息量越大,熵就越大,最大熵算法就是找出一个最佳阈值使得背景与前景两个部分熵之和最大。

给定一个大小为M*N的图像,直方图中所有矩形框所代表的数值之和,即为图像中的像素数量,设像素值i的像素在图中有h(i)个,即:

\sum_{i=0}^{K-1}h(i)=MN

相对应的归一化直方图表示为:

p(i)=\frac{h(i)}{MN}

其中0<=i<K。通常被解释为一个随机过程的概率分布或概率密度函数,p(i)表示的是图像中像素灰度值为i所出现的概率。i的累积概率值为1,即概率分布p必须满足以下关系:

\sum_{i=0}^{K-1}p(i)=1

与累积概率所对应的累积直方图H是一个离散的分布函数P()(通常也称为累积分布函数或cdf),P(i)表示像素值小于等于i的概率:

P(i)=\sum_{j=0}^{i}p(j)

在图像处理中,灰度图的熵定义如下:

Entropy=-\sum_{i=0}^{K-1}p(i)log_2p(i)

因为p(i)\in \left [ 0,1 \right ],所以log_2p(i)<0,-log_2p(i)>0

利用图像熵为准则进行图像分割有一定历史了,学者们提出了许多以图像熵为基础进行图像分割的方法。以下介绍一种由Kapuret al提出来,现在仍然使用较广的一种图像熵分割方法。

给定一个特定的阈值q(0<=q<K-1),对于该阈值所分割的两个图像区域C0,C1,这两部分的熵可写为:

H(0)=- \sum_{i=0}^{q}\frac{p(i)}{P_0(q)}log_2\frac{p(i)}{P_0(q)}

H(1)=- \sum_{i=q+1}^{K-1}\frac{p(i)}{P_1(q)}log_2\frac{p(i)}{P_1(q)}

其中:P_0(q)=\sum_{i=0}^{q}p(i)P_1(q)=\sum_{i=q+1}^{K-1}p(i)P_0(q)+P_1(q)=1

图像总熵为:H_q=H(0)+H(1)现在就是要遍历q(0<=q<K-1),使得Hq最大。

为了计算方便,对H(0)和H(1)的表达式进行优化:

H(0)=- \sum_{i=0}^{q}\frac{p(i)}{P_0(q)}\left ( log_2p(i)-log_2P_0(q) \right ) =-\frac{1}{P_0(q)}[\sum_{i=0}^{q}p(i)log_2p(i)-log_2P_0(q)\sum_{i=0}^{q}p(i)]

得到H(0)=\frac{1}{P_0(q)}S_0(q)+log_2P_0(q)

同理H(1)=\frac{1}{P_1(q)}S_1(q)+log_2P_1(q)

其中S_0(q)=-\sum_{i=0}^{q}p(i)log_2p(i)S_1(q)=-\sum_{i=q+1}^{K-1}p(i)log_2p(i)

import cv2
import matplotlib.pylab as plt
import numpy as np
import mathdef calcGrayHist(image):rows, cols = image.shape[:2]grayHist = np.zeros([256], np.uint64)for row in range(rows):for col in range(cols):grayHist[image[row][col]] += 1return grayHistdef thresh_entropy(image):rows, cols = image.shape# 求灰度直方图grayHist = calcGrayHist(image)# 归一化灰度直方图,即概率直方图normGrayHist = grayHist / float(rows*cols)  # 就是上面讲的p(i)# 1.计算累加直方图zeroCumuMoment = np.zeros([256], np.float32) # 就是上面讲的P(i)for i in range(256):if i == 0:zeroCumuMoment[i] = normGrayHist[i]else:zeroCumuMoment[i] = zeroCumuMoment[i-1] + normGrayHist[i]# 2.计算各个灰度级的熵entropy = np.zeros([256], np.float32)  # 就是上面讲的S_0(q)for i in range(256):if i == 0:if normGrayHist[i] == 0:  # 0log2_0是0,但是对数在0处没有定义entropy[i] = 0else:entropy[i] = -normGrayHist[i] * math.log2(normGrayHist[i])else:if normGrayHist[i] == 0:entropy[i] = entropy[i-1] # 0log2_0是0,但是对数在0处没有定义else:entropy[i] = entropy[i-1] - normGrayHist[i] * math.log2(normGrayHist[i])# 3.找阈值fT = np.zeros([256], np.float32)ft1, ft2 = 0.0, 0.0totalEntropy = entropy[255]for i in range(255):# 找最大值ft1 = entropy[i] / zeroCumuMoment[i] + math.log2(zeroCumuMoment[i])ft2 = (entropy[255] - entropy[i]) / (1 - zeroCumuMoment[i]) + math.log2(1 - zeroCumuMoment[i])fT[i] = ft1 + ft2# 找最大值的索引,作为得到的阈值print(fT)threshLoc = np.where(fT == np.max(fT))thresh = threshLoc[0][0]# 阈值处理threshold = np.copy(image)threshold[threshold>thresh] = 255threshold[threshold<=thresh] = 0return thresh, thresholddef main():img = cv2.imread("6.jpg", 0)thresh, threshImg = thresh_entropy(img)print(thresh) # 结果是104.0titles = ['Original Image', 'After Binarization']images = [img, threshImg]for i in range(2):plt.subplot(1, 2, i + 1)plt.imshow(images[i], 'gray')plt.title(titles[i])plt.xticks([])plt.yticks([])plt.show()main()

相关文章:

  • 粤嵌实训医疗项目--day06(Vue + SpringBoot)
  • 2023年云计算的发展趋势
  • 取暖器/暖风机上架 亚马逊美国站UL1278测试标准要求
  • activiti命令模式与责任链模式
  • DDoS攻击剧增,深入解析抗DDoS防护方案
  • 设计模式之模版方法(TemplateMethod)
  • Spring Boot 整合xxl-job实现分布式定时任务
  • STM32GPIO——上拉、下拉电阻
  • uniapp在IOS手机下解决时间nan-an-nan问题
  • MYSQL迁移到人大金仓后的适配问题汇总
  • Facebook个人主页和公共主页的区别
  • 新型的铁塔基站“能源管家”
  • @KafkaListener注解详解(一)| 常用参数详解
  • “谐波”分析治理,电能质量在线监测
  • ‘XXX‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。 系统找不到指定的路径。
  • (三)从jvm层面了解线程的启动和停止
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • js
  • js对象的深浅拷贝
  • Kibana配置logstash,报表一体化
  • Material Design
  • Ruby 2.x 源代码分析:扩展 概述
  • Vue.js 移动端适配之 vw 解决方案
  • vue从创建到完整的饿了么(18)购物车详细信息的展示与删除
  • 漂亮刷新控件-iOS
  • 使用权重正则化较少模型过拟合
  • 手机端车牌号码键盘的vue组件
  • 一天一个设计模式之JS实现——适配器模式
  • FaaS 的简单实践
  • 阿里云服务器购买完整流程
  • ​​​​​​​​​​​​​​Γ函数
  • ​力扣解法汇总946-验证栈序列
  • # Panda3d 碰撞检测系统介绍
  • #{}和${}的区别是什么 -- java面试
  • #AngularJS#$sce.trustAsResourceUrl
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • (2)(2.4) TerraRanger Tower/Tower EVO(360度)
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (52)只出现一次的数字III
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (草履虫都可以看懂的)PyQt子窗口向主窗口传递参数,主窗口接收子窗口信号、参数。
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (利用IDEA+Maven)定制属于自己的jar包
  • (四)JPA - JQPL 实现增删改查
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • (转)http协议
  • (转)菜鸟学数据库(三)——存储过程
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • .apk文件,IIS不支持下载解决