数字图像处理(十二)最大熵算法

news2024/9/22 12:47:59

文章目录

  • 前言
  • 一、熵是什么?
    • 1.信息量如何计算?
    • 2.熵如何计算?
  • 二、最大熵方法
    • 1.设计思想
    • 2.算法步骤
    • 3.C++代码
    • 4.实验结果
  • 参考资料


前言

在图像分析中,通常需要将所关心的目标从图像中提取出来,这种从图像中某个特定区域与其他部分进行分离并提取出来的处理,就是图像分割。所以图像分割处理实际上就是区分图像中的“前景目标”和“背景”,所以通常又称之为图像的二值处理。之前我们已经介绍过基于图像灰度分布的阈值方法和大津二值化算法。今天我们再介绍一种二值化算法:最大熵方法。

一、熵是什么?

  是信息论中对不确定性的度量,是对数据中所包含信息量大小的度量。熵取最大值时,就表明获得的信息量最大。
信息量:信息量有大有小。比如太阳从东边升起,这是一个确定的事件,没有一点信息量;比如说某人买了一张彩票,有99%的概率会中奖,那这个事情信息量就很大,因为本来概率很小很小的事情变得很确定了。

1.信息量如何计算?

  一个事件的信息量就是这个事件发生的概率的负对数。
例如,符号 x x x出现的概率为 p ( x ) p(x) p(x),则符号 x x x的自信息量 I I I I = − l o g p ( x ) I=-logp(x) I=logp(x)

2.熵如何计算?

  假设符号集有 n n n个符号,每个符号出现的概率为 p ( x i ) p(x_i) p(xi),则符号集的信息熵为 H = − ∑ i = 1 n p ( x i ) l o g p ( x i ) H=-\sum_{i=1}^np(x_i)logp(x_i) H=i=1np(xi)logp(xi)
可以得到一个结论: p ( x 1 ) = p ( x 2 ) = ⋯ = p ( x n ) p(x_1)=p(x_2)=\cdots=p(x_n) p(x1)=p(x2)==p(xn)时熵取最大值。

二、最大熵方法

1.设计思想

最大熵方法的设计思想是:选择适当的阈值将图像分为两类,两类的平均熵之和最大时,可以从图像中获得最大信息量,以此来确定最佳阈值。

2.算法步骤

  1. 求出图像中的所有像素的分布概率 p 0 , p 1 , ⋯   , p 255 p_0,p_1,\cdots,p_{255} p0,p1,,p255(图像的灰度分布范围为[0,255]) p i = N i N i m a g e p_i=\frac{N_i}{N_{image}} pi=NimageNi其中, N i N_i Ni为灰度值为 i i i的像素个数; N i m a g e N_{image} Nimage为图像的总像素数;
  2. 给定一个初始阈值 T h = T h 0 Th=Th_0 Th=Th0 T h ∈ [ 0 , 255 ] Th\in[0,255] Th[0,255];将图像分为 C 1 C_1 C1 C 2 C_2 C2两类;
  3. 分别计算两个类的平均相对熵 E 1 = − ∑ i = 0 T h ( p i / p T h ) ⋅ l n ( p i / p T h ) E_1=-\sum_{i=0}^{Th}(p_i/p_{Th})\cdot ln(p_i/p_{Th}) E1=i=0Th(pi/pTh)ln(pi/pTh) E 2 = − ∑ i = T h + 1 255 ( p i / ( 1 − p T h ) ) ⋅ l n ( p i / ( 1 − p T h ) ) E_2=-\sum_{i=Th+1}^{255}(pi/(1-p_{Th}))\cdot ln(p_i/(1-p_{Th})) E2=i=Th+1255(pi/(1pTh))ln(pi/(1pTh))其中 p T h = ∑ i = 0 T h p i p_{Th}=\sum_{i=0}^{Th}p_i pTh=i=0Thpi
  4. E 1 + E 2 E_1+E_2 E1+E2之和为最大值时,此时的 T h Th Th为最佳阈值 T h ∗ Th^* Th,此时满足图像中的信息量最大。

3.C++代码

/* 最大熵算法 */
int main()
{
    cv::Mat image = cv::imread("Lena.bmp");
    cv::Mat gray_image = cv::Mat::zeros(image.size(), CV_8UC1);
    cv::cvtColor(image, gray_image, cv::COLOR_BGR2GRAY);

    int height = gray_image.rows;
    int width = gray_image.cols;

    // 计算像素分布概率
    float p[256] = { 0 };
    for (int row = 0; row < height; row++)
    {
        for (int col = 0; col < width; col++)
        {
            p[gray_image.at<uchar>(row, col)] = p[gray_image.at<uchar>(row, col)] + 1;
        }
    }
    for (int i = 0; i < 256; i++)
    {
        p[i] = p[i] / (height*width);
    }
    //保存E_1+E_2
    float E[256] = { 0.0 };

    //遍历所有的像素值
    int index = 0; //最大值的索引
    for (int th = 0; th < 256; th++)
    {
        // 计算p_Th
        float p_Th = 0.0;
        for (int i = 0; i < th+1; i++)
        {
            p_Th += p[i];
        }

        // 计算E_1
        float E_1 = 0.0, E_2 = 0.0;

        for (int i = 0; i < th + 1; i++)
        {
            if (fabs(p_Th) < 1e-6)
            {
                E_1 = 0;
            }
            else
            {
                E_1 += -(p[i] / p_Th) * log(p[i] / p_Th + 1e-6);
            }
            
        }
        for (int j = th + 1; j < 256; j++)
        {
            if (fabs(1 - p_Th) < 1e-6)
            {
                E_2 = 0;
            }
            else
            {
                E_2 += -(p[j] / (1 - p_Th))*log(p[j] / (1 - p_Th)+1e-6);
            }
        }
        if ((E_1 + E_2) > E[index])
        {
            index = th;
        }
        E[th] = E_1+E_2;
    }

    // 进行二值化
    cv::Mat output_image = cv::Mat::zeros(height, width, CV_8UC1);
    for (int row = 0; row < height; row++)
    {
        for (int col = 0; col < width; col++)
        {
            if (gray_image.at<uchar>(row, col) > index)
            {
                output_image.at<uchar>(row, col) = 255;
            }
            else
            {
                output_image.at<uchar>(row, col) = 0;
            }
        }
    }
    cv::imshow("input-image", gray_image);
    cv::imshow("output-image", output_image);
    cv::waitKey(0);
    return 0;
}

关于代码的几点说明:

  1. 因为除数可能是0,所以要对p_Th进行为0判断。可以参考C++ float、double判断是否等于0,1-p_Th同理。
  2. 因为log()函数括号内可能取到0,从而出现负无穷的情况,所以加上一个很小的整数1e-6,避免出现负无穷的情况。

4.实验结果

在这里插入图片描述

参考资料

1.数字图像处理基础.朱虹.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/32962.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JAVA中的集合类型的理解及应用

目录 概述 List和Queue Map和Set HashTable和HashMap的区别 Queue和Deque BlockingQueue 并发集合 概述 写程序免不了处理一些批量数据&#xff0c;不同数据结构和算法&#xff0c;会带来不同的性能效果。大学的计算机课程中就有一门叫《数据结构》的课程&#xff0c;这门…

总结我的 MySQL 学习历程,给有需要的人看

作者| 慕课网精英讲师 马听 你好&#xff0c;我是马听&#xff0c;现在是某零售公司的 MySQL DBA&#xff0c;身处一线的我表示有很多话要讲。 我的MySQL学习历程 在我大三的时候&#xff0c;就开始接触到 MySQL 了&#xff0c;当时我也是从最基础的 MySQL 知识&#xff08;…

6、项目第六阶段——用户名登录显示和注册验证码

第六阶段——用户名登录显示和注册验证码 1、登陆—显示用户名 UserServlet 程序中保存用户登录的信息 UserServlet程序中&#xff1a; //保存用户登录信息到Session域中 req.getSession().setAttribute("user",loginUser);修改 login_succuess_menu.jsp&#xf…

2019 国际大学生程序设计竞赛(ICPC)亚洲区域赛(银川) 7题

文章目录N.Fibonacci SequenceB.So EasyI.Base62G.Pot!!F.Function!K.Largest Common Submatrix补题链接&#xff1a;https://codeforces.com/gym/104021 难得VP打出这么好的成绩&#xff0c;虽然是有争议的西部枢纽银川站&#xff0c;虽然没能早生几年。。。。 N.Fibonacci Se…

【数据结构】基础:堆

【数据结构】基础&#xff1a;堆 摘要&#xff1a;本文主要介绍数据结构堆&#xff0c;分别介绍其概念、实现和应用。 文章目录【数据结构】基础&#xff1a;堆一、概述1.1 概念1.2 性质二、实现2.1 定义2.2 初始化与销毁2.3 入堆2.4 出堆2.5 堆的创建2.6 其他三、应用3.1 堆排…

《前端》css总结(下)

文章目录元素展示格式displaywhite-spacetext-overflowoverflow内边距和外边距marginpadding盒子模型box-sizing位置position&#xff1a;用于指定一个元素在文档中的定位方式浮动flex布局flex-directionflex-wrapflex-flowjustify-contentalign-itemsalign-contentorderflex-g…

你最少用几行代码实现深拷贝?

问题分析 深拷贝 自然是 相对 浅拷贝 而言的。 我们都知道 引用数据类型 变量存储的是数据的引用&#xff0c;就是一个指向内存空间的指针&#xff0c; 所以如果我们像赋值简单数据类型那样的方式赋值的话&#xff0c;其实只能复制一个指针引用&#xff0c;并没有实现真正的数…

计算机组成原理4小时速成:存储器,内存ROM,RAM,Cache,高速缓存cache,外存,缓存命中率,效率

计算机组成原理4小时速成&#xff1a;存储器&#xff0c;内存ROM,RAM,Cache&#xff0c;高速缓存cache&#xff0c;外存&#xff0c;缓存命中率&#xff0c;效率 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法…

MYSQL事务原理分析

目录事务是什么ACID特性原子性&#xff08;A&#xff09;隔离性&#xff08;I&#xff09;持久性&#xff08;D&#xff09;一致性&#xff08;C&#xff09;隔离级别简介有些什么READ UNCOMMITTED&#xff08;读未提交&#xff09;READ COMMITTED&#xff08;读已提交&#xf…

【17】Java常见的面试题汇总(设计模式)

目录 1. 说一下你熟悉的设计模式&#xff1f; 2. 简单工厂和抽象工厂有什么区别&#xff1f; 1. 说一下你熟悉的设计模式&#xff1f; 单例模式&#xff1a;保证被创建一次&#xff0c;节省系统开销。 工厂模式&#xff08;简单工厂、抽象工厂&#xff09;&#xff1a;解耦…

力扣(LeetCode)60. 排列序列(C++)

枚举 枚举每一位可能的数字。 如图。算法流程如上图。 思路分析 : 一个数 nnn &#xff0c;可以组成的排列数量有 n!n!n! 。当首位确定&#xff0c;剩余位能组成的排列数量 (n−1)!(n-1)!(n−1)! &#xff0c;依次类推 (n−2)!/(n−3)!/(n−4)!/…/2!/1!/0!(n-2)!/(n-3)!/(n…

CentOS7安装MYSQL8.X的教程详解

1-首先查看系统是否存在mysql&#xff0c;无则不返回 1 # rpm -qa|grep mysql 2-安装wget 1 # yum -y install wget 3-抓取mariadb并删除包&#xff0c;无则不返回 1 # rpm -qa|grep mariadb 4-删除mariadb-libs-5.5.68-1.el7.x86_64 1 # rpm -e --nodeps mariadb-libs-…

本节作业之数组求和及其平均值、求数组最大值、最小值、数组转换为分割字符串、新增数组案例、筛选数组案例、删除指定数组元素、翻转数组、数组排序(冒泡排序)

本节作业之数组求和及其平均值、求数组最大值、最小值、数组转换为分割字符串、新增数组案例、筛选数组案例、删除指定数组元素、翻转数组、数组排序<冒泡排序>求数组[2,6,1,7,4]里面所有的元素的和以及平均值求数组[2,6,1,77,52,25,7]中的最大值求数组[2,6,1,77,52,25,7…

Linux - netstat 查看系统端口占用和监听情况

文章目录功能语法示例显示 tcp&#xff0c;udp 的端口和进程Show both listening and non-listening socketsList all tcp ports.List all udp portsList only listening portsList only listening TCP ports.List only listening UDP ports.List only the listening UNIX port…

Android 性能优化方法论【总结篇】

作为一位多年长期做性能优化的开发者&#xff0c;在这篇文章中对性能优化的方法论做一些总结&#xff0c;以供大家借鉴。 性能优化的本质 首先&#xff0c;我先介绍一下性能优化的本质。我对其本质的认知是这样的&#xff1a;性能优化的本质是合理且充分的使用硬件资源&#x…

分享感恩节联系客户话术

看了一眼在手边的日历&#xff0c;发现今天是11月24日&#xff0c;一年一度的感恩节又到了&#xff0c;不得不感叹时间过得真快&#xff0c;每年十一月的第四个星期四是感恩节。 随着各国多元文化的发展&#xff0c;感恩节也越来越被世界各地传颂&#xff0c;多少都会有一些影…

WANLSHOP 直播短视频种草多用户电商系统源码自营+多商户+多终端(H5+小程序+APP)

WANLSHOP高级版 可用于自营外包项目(多主体)、 可用于外包定制开发项目、 提供开源源码&#xff0c;私有化部署、一款基于 FastAdmin Uni-APP 开发的 多终端&#xff08;H5移动端、APP、微信小程序、微信公众号&#xff09;、多用户商城系统拥有多种运营模式B2B2C/B2C&#xf…

python安装依赖库

一、安装pip 1、打开终端&#xff0c;输入&#xff1a; pip3 install tushare -i https://pypi.douban.com/simple 2、验证是否安装成功 打开终端&#xff0c;输入&#xff1a;pip3 出现以上页面&#xff0c;则安装成功 二、安装flask 1、打开终端&#xff0c;输入&…

mybatis-plus学习笔记

文章目录1 简介2 初始化项目2.1引入pom2.2 引入lombok插件2.3 配置信息2.4 创建实体类2.5 创建mapper2.6 配置注解MapperScan2.7 编写测试类2.8 配置MyBatis日志3 测试基本的CRUD3.1 新增3.2 查询3.3 修改3.4 删除4 自定义动态sql5 Service 层使用mybatis-plus方法5.1 service层…

使用hive进行大数据项目分析

目录 一、首先要创建表&#xff1a;在txt记事本中先输入创建语句备用&#xff0c;创建class1~class5的表。 二、启动hadoop集群&#xff0c;MySQL&#xff0c;hive。 三、创建数据库zhh&#xff0c;用户为zhh&#xff0c;之后将之前写在txt记事本里的创建表class1~class5的命…