opencv--使用直方图找谷底进行确定分割阈值
直方图原理就不说了,大家自行百度
直方图可以帮助分析图像中的灰度变化,进而帮助确定最优二值化的灰度阈值(threshold level)。如果物体与背景的灰度值对比明显,此时灰度直方图就会包含双峰(bimodal histogram),即直方图中一般会有两个峰值,分别为图像的前景和背景。
前景使得某个灰度区间的灰度值的数量急剧增加,就会产生一个峰值,同理背景会使另一个灰度区间的灰度值的数量急剧增加,就产生另外一个峰值,两峰间的谷底对应于物体边缘附近相对较少数目的像素点。
这两个峰值之间的最小值一般就是最优二值化的分界点,通过这个分界点可以把前景和背景很好地分割开来。

有时这两个峰值会有部分重叠,即左侧峰值的下降部分和右侧峰值的上升部分存在叠加。通常可以把自然界的信号看做高斯信号,即一个峰值对应一个高斯信号,当直方图中的两个高斯信号在某个灰度区域叠加的时候,其叠加区就形成了一个圆滑的谷底,就很难找到一个确切的位置(最优二值化的灰度值)把这两个峰值分开。
float calculateThreshold(cv::Mat& img)
{cv::Mat temp = img.clone();// 计算直方图cv::Mat hist;int histSize = 256; // 直方图尺寸float range[] = { 0, 256 }; // 像素值范围const float* ranges[] = { range };cv::calcHist(&img, 1, nullptr, cv::Mat(), hist, 1, &histSize, ranges);/*for (int i = 0; i < 21; i++)hist.at<float>(i, 0) = 0.0;*/cv::normalize(hist, hist, 0, 1, cv::NORM_MINMAX);//hist.convertTo(hist, CV_32S);cv::GaussianBlur(hist, hist, cv::Size(0, 0),3,3);//cv::blur(hist, hist, cv::Size(1, 9),cv::Point(-1,-1));std::vector<float> peaks; // 存储峰值位置std::vector<float> valleys; // 存储低谷位置for (int i = 1; i < histSize - 1; i++) {//std::cout << std::fixed << std::setprecision(4);float currentValue = hist.at<float>(i);float prevValue = hist.at<float>(i - 1);float nextValue = hist.at<float>(i + 1);/*if (currentValue < 0.001)continue;*/// 具体情况需要修改currentValue>0.005的阈值if ((currentValue > prevValue && currentValue > nextValue && currentValue>0.005)) {std::cout << prevValue << " " << currentValue << " " << nextValue << std::endl;peaks.push_back(i); // 峰值}else if (currentValue < prevValue && currentValue < nextValue && currentValue>0.001) {std::cout << prevValue << " " << currentValue << " " << nextValue << std::endl;valleys.push_back(i); // 低谷}}if(valleys.size()>0)cv::threshold(temp, temp, valleys[0], 255, cv::THRESH_BINARY);// 创建直方图可视化图像int histWidth = 512;int histHeight = 400;cv::Mat histImage(histHeight, histWidth, CV_8UC3, cv::Scalar(0, 0, 0));cv::Mat hist_temp;// 归一化直方图数据cv::normalize(hist, hist_temp, 0, histImage.rows, cv::NORM_MINMAX, -1, cv::Mat());// 绘制直方图int binWidth = cvRound((double)histWidth / histSize);for (int i = 0; i < histSize; i++) {int binHeight = cvRound(hist_temp.at<float>(i));cv::line(histImage, cv::Point(i * binWidth, histHeight), cv::Point(i * binWidth, histHeight - binHeight), cv::Scalar(255, 255, 255));}if (valleys.size() > 0)return valleys[0];return 0;
}


相关文章:
opencv--使用直方图找谷底进行确定分割阈值
直方图原理就不说了,大家自行百度 直方图可以帮助分析图像中的灰度变化,进而帮助确定最优二值化的灰度阈值(threshold level)。如果物体与背景的灰度值对比明显,此时灰度直方图就会包含双峰(bimodal histo…...
dolphinscheduler海豚调度(四)钉钉告警
在之前的博文中,我们已经介绍了DolphinScheduler海豚调度的基本概念和工作流程,以及Shell任务和SQL任务的实践。今天,让我们来学习DolphinScheduler中的另一个重要功能:钉钉告警。 钉钉群添加机器人 在钉钉群添加机器人…...
Java-Safe Point(安全点)
虽然安全点的概念和垃圾回收相关,但是概念还是比较独立的,所以本文是从这篇文章Java-虚拟机-垃圾收集器/垃圾收集算法/GCROOT根中抽出来的 安全点safe point 当执行垃圾回收(GC)的时候,不是立马就执行的,…...
大数据旅游数据分析:基于Python旅游数据采集可视化分析推荐系统
文章目录 基于Python旅游数据采集可视化分析推荐系统一、项目概述二、项目说明三、开发环境四、功能实现五、系统页面实现用户登录注册系统首页数据操作管理价格与销量分析旅游城市和景点等级分析旅游数据评分情况分析旅游数据评论情况分析旅游景点推荐Django系统后台管理 六、…...
打造智能汽车微服务系统平台:架构的设计与实现
随着智能汽车技术的飞速发展,微服务架构在汽车行业中的应用越来越广泛。采用微服务架构可以使汽车系统更加灵活、可扩展,并且有利于快速推出新功能和服务。本文将从设计原则、关键技术、数据安全等方面,介绍如何搭建智能汽车微服务系统平台架…...
机试指南:Ch5:线性数据结构 Ch6:递归与分治
文章目录 第5章 线性数据结构1.向量 vector2.队列 queue(1)队列的特点、应用(2)基本操作(3)例题例题1:约瑟夫问题2 (难度:中等) (4)习题习题1:排队打饭 (难度:中等) 3.栈 stack(1)栈…...
展厅设计的理念是什么
1、立足当地文化 升华本地精神 ,因地制宜,深入挖掘本土文化特色,撷取其精华,灵活运用、巧妙融入,做到掌控宏观全局。 重点突出,努力打造本土拳头品牌,挖掘其内涵,拓展延伸、着重展示…...
springboot 定时任务备份mysql数据库
记录在Linux 系统上定时备份MySQL数据库 1、在代码中添加备份 package org.jeecg.modules.xczxhhr.job;import lombok.extern.slf4j.Slf4j; import org.quartz.Job; import org.quartz.JobExecutionContext;import java.io.BufferedReader; import java.io.File; import java…...
PMP考试之20240301
1、在回顾项目团队最新的绩效报告时,项目经理注意到他们的产出出现了重大下降。项目经理决定: A.增加每个团队成员在截止日期前完成任务的压力 B.增加状态报告和团队评审会议的频率 C.为表现最好的团队成员提供特别奖励 D.改善和促进团队成员之间的信任和凝聚力…...
什么是MAC地址? win10电脑查看MAC地址的多种方法
您是否知道连接到家庭网络的每件硬件都有自己的身份?正如每个设备都分配有自己的 IP 地址一样,每个硬件都有一个唯一的网络标识符。 该标识符称为MAC 地址。MAC 代表媒体访问控制。您可能需要 MAC 地址来解决网络问题或配置新设备。在 Windows 中查找您…...
vue3中的基本语法
目录 基础素材 vue3的优化 使用CompositionAPI理由 1. reactive() 函数 2. ref() 函数 2.1. ref的使用 2.2. 在 reactive 对象中访问 ref 创建的响应式数据 3. isRef() 函数 4. toRefs() 函数 5. computed() 5.1. 通过 set()、get()方法创建一个可读可写的计算属性 …...
Timeplus-proton流处理器调研
概念 Timeplus是一个流处理器。它提供强大的端到端功能,利用开源流引擎Proton来帮助数据团队快速直观地处理流数据和历史数据,可供各种规模和行业的组织使用。它使数据工程师和平台工程师能够使用 SQL 释放流数据价值。 Timeplus 控制台可以轻松连接到不…...
H3C防火墙安全授权导入
一、防火墙授权概述 前面我们已经了解了一些防火墙的基本概念,有讲过防火墙除了一些基本功能,还有一些高级安全防护,但是这些功能需要另外独立授权,不影响基本使用。这里以H3C防火墙为例进行大概了解下。 正常情况下,防…...
使用 OpenCV 通过 SIFT 算法进行对象跟踪
本文介绍如何使用 SIFT 算法跟踪对象 在当今世界,当涉及到对象检测和跟踪时,深度学习模型是最常用的,但有时传统的计算机视觉技术也可能有效。在本文中,我将尝试使用 SIFT 算法创建一个对象跟踪器。 为什么人们会选择使用传统的计…...
SHELL 脚本: 导出NEO4j DUMP并上传SFTP
前提 开通sftp账号 安装expect 示例 NEO4J_HOME/path/to/neo4j # neo4j 安装目录 DUMP_PATH/data/dump # DUMP本地保存目录 DUMP_FILEneo4j_$(date %F).dump #导出文件名称 UPLOAD_DIR/path/to/stfp/dump/ #上传目录 $NEO4J_HOME/bin/neo4j-admin dump --databaseneo4j --t…...
Vue 封装一个函数,小球原始高度不固定,弹起比例不固定、计算谈几次后,高度低于1米
## 简介 本文将介绍如何使用Vue封装一个函数,计算小球弹跳的次数,直到高度低于1米。函数的参数包括小球的原始高度和弹起比例。通过代码案例演示了如何使用Vue进行封装和调用。 ## 函数封装 vue <template> <div> <label for&qu…...
外地人能申请天津公租房吗?2024天津积分落户租房积分怎么加?
相关推荐:在天津工作的外地人可以申请天津公共租赁住房吗? 外地人可以申请天津公共租赁住房吗? 2024年定居天津租房如何加分? 根据《天津居住证积分指标及积分表》的规定,在天津租房也可以参加积分结算,每…...
毕业设计——基于springboot的聊天系统设计与实现(服务端 + 客户端 + web端)
整个工程包含三个部分: 1、聊天服务器 聊天服务器的职责一句话解释:负责接收所有用户发送的消息,并将消息转发给目标用户。 聊天服务器没有任何界面,但是却是IM中最重要的角色,为表达敬意,必须要给它放个…...
公告栏功能:自动弹出提醒,重要通知不再错过
发布查询时,您是否遇到这样的困扰: 1、查询发布时间未到,学生进入查询主页后发现未发布任何查询,不断进行咨询。 2、有些重要事项需要进入查询主页就进行强提醒,确保人人可见,用户需要反馈“我知道了”才能…...
网络编程学习
思维导图 代码练习 TCP实现通信 服务器端代码 #include <myhead.h> #define SER_IP "192.168.152.135" #define SER_PORT 8910 int main(int argc, const char *argv[]) {//1创建用于监听的套接字int sfd -1;sfd socket(AF_INET,SOCK_STREAM,0)…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...
