03篇--二值化与自适应二值化
二值化
定义
何为二值化?顾名思义,就是将图像中的像素值改为只有两种值,黑与白。此为二值化。
二值化操作的图像只能是灰度图,意思就是二值化也是一个二维数组,它与灰度图都属于单信道,仅能表示一种色调。而二值化表示的是 极致的黑 与 极致的白。

如何设置二值化
1.阈值法(THRESH_BINARY)
通过设置一个阈值,将灰度图中的每一个像素值与该阈值进行比较,小于等于阈值的像素就被设置为0(黑),大于阈值的像素就被设置为maxval(白)。

原理代码如下:
import cv2
import numpy as np# 读取彩色图
img = cv2.imread("./flower.png")# 先转换成灰度图
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)img_binary = np.zeros_like(img_gray)# 设置一个阈值
thresh = 127# 遍历灰度图的每一个像素点
for i in range(img_gray.shape[0]):for j in range(img_gray.shape[1]):if img_gray[i][j] <= thresh:img_binary[i, j] = 0else:img_binary[i, j] = 255cv2.imshow('image', img)
cv2.imshow('image_gray', img_gray)
cv2.imshow('image_binary', img_binary)
cv2.waitKey(0)
效果如下:


2.反阈值法(THRESH_BINARY_INV)
与阈值法相反。反阈值法是当灰度图的像素值大于阈值时,该像素值将会变成0(黑),当灰度图的像素值小于等于阈值时,该像素值将会变成maxval(白)。

原理代码:
跟上面阈值法的代码一样,只是把 >= 换成 <= ,将筛选对象调换即可


将阈值法与反阈值法的处理结果对比,可以发现,两者的黑白色调刚好相反
3.截断阈值法(THRESH_TRUNC):
指将灰度图中的所有像素与阈值进行比较,像素值大于阈值的部分将会被修改为阈值,小于等于阈值的部分不变。换句话说,经过截断阈值法处理过的二值化图中的最大像素值就是阈值。

4.低阈值零处理(THRESH_TOZERO)
就是像素值小于等于阈值的部分被置为0(也就是黑色),大于阈值的部分不变。

5.超阈值零处理(THRESH_TOZERO_INV)
就是将灰度图中的每个像素与阈值进行比较,像素值大于阈值的部分置为0(也就是黑色),像素值小于等于阈值的部分不变。

6.OTSU阈值法(THRESH_OTSU)
在介绍OTSU阈值法之前,我们首先要了解一下双峰图片的概念。
双峰图片就是指灰度图的直方图上有两个峰值,直方图就是对灰度图中每个像素值的点的个数的统计图,如下图所示。

OTSU算法是通过一个值将这张图分前景色和背景色(也就是灰度图中小于这个值的是一类,大于这个值的是一类),通过统计学方法(最大类间方差)来验证该值的合理性,当根据该值进行分割时,使用最大类间方差计算得到的值最大时,该值就是二值化算法中所需要的阈值。通常该值是从灰度图中的最小值加1开始进行迭代计算,直到灰度图中的最大像素值减1,然后把得到的最大类间方差值进行比较,来得到二值化的阈值。具体实现过程,我们不用考虑,直接调用即可。
threshold函数
上述方法只是介绍其原理,在opencv库中这些方法都已经被封装好了,我们只需要调用这些接口即可,并不需要我们手动实现。通过threshold函数来调用,具体介绍如下:

功能:用于对图像进行二值化处理
参数:
- src: 输入图像,这应该是一个灰度图像(即单通道图像)。如果你有一个彩色图像,你需要先使用 cv2.cvtColor() 将其转换为灰度图。
- thresh: 阈值,用于将像素划分为两部分。这个值是一个浮点数或整数,取决于图像的数据类型。
- maxVal: 最大值,用于设置高于阈值的像素值。这个值通常是一个整数,表示你想要将高于阈值的像素设置为的具体数值。
- type: 阈值类型,这是一个标志,用于指定如何应用阈值。OpenCV 提供了几种不同的阈值类型,如 cv2.THRESH_BINARY、cv2.THRESH_BINARY_INV、cv2.THRESH_TRUNC、cv2.THRESH_TOZERO 和 cv2.THRESH_TOZERO_INV。
- dst: 输出图像,与输入图像具有相同的大小和类型。这是一个可选参数,如果不提供,函数会创建一个新的图像来存储二值化结果。(一般不会设置这个参数)
函数返回值:
- ret: 实际使用的阈值。在某些情况下(如使用 cv2.THRESH_OTSU 或 cv2.THRESH_TRIANGLE 标志时),这个值可能会与输入的 thresh 不同。(因为这两个算法会自动计算阈值,从而覆盖掉你所设置的阈值)
- dst: 二值化后的图像。
代码示例
import cv2# 读取彩色图
img = cv2.imread("./flower.png")# 先转换成灰度图
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 调用cv2的二值化函数
ret, img_binary = cv2.threshold(img_gray, 200, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
print(ret) # 使用的阈值,可能不是你设定的阈值cv2.imshow('image', img)
cv2.imshow('image_gray', img_gray)
cv2.imshow('image_binary', img_binary)
cv2.waitKey(0)
自动化二值化
与二值化算法相比,自适应二值化更加适合用在明暗分布不均的图片,因为图片的明暗不均,导致图片上的每一小部分都要使用不同的阈值进行二值化处理,这时候传统的二值化算法就无法满足我们的需求了,于是就出现了自适应二值化。
adaptiveThreshold函数
自适应二值化方法会对图像中的所有像素点计算其各自的阈值,这样能够更好的保留图片里的一些信息。通过adaptiveThreshold函数调用

功能:对图像应用自适应阈值处理。
参数:
- src: 输入图像,必须为灰度图像。
- maxValue: 超过或等于阈值的像素值被赋予的值。它可以是任意数值,但通常设置为 255(表示白色)。
- adaptiveMethod: 自适应阈值算法的选择。有两种选择:
- cv2.ADAPTIVE_THRESH_MEAN_C:计算邻域的平均值,然后从平均值中减去常数 C。
- cv2.ADAPTIVE_THRESH_GAUSSIAN_C:计算邻域像素的加权和(使用高斯窗口),然后从加权和中减去常数 C。
- thresholdType: 阈值类型,与固定阈值函数 cv2.threshold() 相同。通常是 cv2.THRESH_BINARY 或 cv2.THRESH_BINARY_INV。
- blockSize: 用于计算阈值的邻域大小(必须是奇数)也就是核。
- C: 从计算出的平均值或加权和中减去的常数。
import cv2# 读取彩色图
img = cv2.imread("./lena.png")# 先转换成灰度图
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 调用自适应二值化函数
img_adaptive = cv2.adaptiveThreshold(img_gray, # 参数1 灰度图255, # 参数2 最大值cv2.ADAPTIVE_THRESH_GAUSSIAN_C, # 参数3 自适应方法cv2.THRESH_BINARY, # 参数4 二值化类型7, # 参数5 核的大小5 # 参数6 计算的阈值减去这个常数是最终阈值)
cv2.imshow('image', img)
cv2.imshow('image_gray', img_gray)
cv2.imshow('image_adaptive_binary', img_adaptive)
cv2.waitKey(0)
相关文章:
03篇--二值化与自适应二值化
二值化 定义 何为二值化?顾名思义,就是将图像中的像素值改为只有两种值,黑与白。此为二值化。 二值化操作的图像只能是灰度图,意思就是二值化也是一个二维数组,它与灰度图都属于单信道,仅能表示一种色调…...
基于python的一个简单的压力测试(DDoS)脚本
DDoS测试脚本 声明:本文所涉及代码仅供学习使用,任何人利用此造成的一切后果与本人无关 源码 import requests import threading# 目标URL target_url "http://47.121.xxx.xxx/"# 发送请求的函数 def send_request():while True:try:respo…...
基于 Spring Boot 实现图片的服务器本地存储及前端回显
??导读:本文探讨了在网站开发中图片存储的各种方法,包括本地文件系统存储、对象存储服务(如阿里云OSS)、数据库存储、分布式文件系统及内容分发网络(CDN)。文中详细对比了这些方法的优缺点,并…...
深入 TCP VJ-Style
接着 TCP 的文化内涵 继续扯一会儿。 自 30 instruction TCP receive 往前追溯,论文 Jacobson88 源自第一次拥塞崩溃,这篇著名文档在同时期的另一个缘起是另一篇考古文献 [Zhang86] Why TCP Timers Don’t Work Well,后面这篇文献提出了 TCP…...
go高性能单机缓存项目
代码 // Copyright 2021 ByteDance Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apach…...
数据结构绪论
文章目录 绪论数据结构三要素算法 🏡作者主页:点击! 🤖数据结构专栏:点击! ⏰️创作时间:2024年12月12日01点09分 绪论 数据是信息的载体,描述客观事物属性的数、字符及所有能输入…...
前端开发常用四大框架学习难度咋样?
前端开发常用四大框架指的是 jQuery vue react angular jQuery: 学习难度:相对较低特点:jQuery 是一个快速、小巧、功能丰富的 JavaScript 库。它使得 HTML 文档遍历和操作、事件处理、动画和 Ajax 交互更加简单。适用场景&a…...
OWASP 十大安全漏洞的原理
1. Broken Access Control(访问控制失效) 原理:应用程序未正确实施权限检查,导致攻击者通过篡改请求、强制浏览或权限提升等手段绕过访问控制。 攻击手段: 修改 URL、HTML、或 API 请求以访问未经授权的资源。 删除…...
论文 | ChunkRAG: Novel LLM-Chunk Filtering Method for RAG Systems
本文详细介绍了一种新颖的检索增强生成(Retrieval-Augmented Generation, RAG)系统方法——ChunkRAG,该方法通过对文档的分块语义分析和过滤显著提升了生成系统的准确性和可靠性。 1. 研究背景与问题 1.1 检索增强生成的意义 RAG系统结合…...
ORACLE SQL思路: 多行数据有相同字段就合并成一条数据 分页展示
数据 分数表: 学号,科目名(A,B,C),分数 需求 分页列表展示, 如果一个学号的科目有相同的分数, 合并成一条数据,用 拼接 科目名 ORACLE SQL 实现 SELECT Z.*, SUBSTR(DECODE(f…...
SpringBoot 手动实现动态切换数据源 DynamicSource (中)
大家好,我是此林。 SpringBoot 手动实现动态切换数据源 DynamicSource (上)-CSDN博客 在上一篇博客中,我带大家手动实现了一个简易版的数据源切换实现,方便大家理解数据源切换的原理。今天我们来介绍一个开源的数据源…...
y3编辑器教学5:触发器2 案例演示
文章目录 一、探索1.1 ECA1.1.1 ECA的定义1.1.2 使用触发器实现瞬间移动效果 1.2 变量1.2.1 什么是变量1.2.2 使用变量存储碎片收集数量并展现 1.3 if语句(魔法效果挂接)1.3.1 地形设置1.3.2 编写能量灌注逻辑1.3.3 编写能量灌注后,实现传送逻…...
数值分析——插值法(二)
文章目录 前言一、Hermite插值1.两点三次Hermite插值2.两点三次Hermite插值的推广3.非标准型Hermite插值 二、三次样条插值1.概念2.三弯矩方程 前言 之前写过Lagrange插值与Newton插值法的内容,这里介绍一些其他的插值方法,顺便复习数值分析. 一、Hermi…...
杨振宁大学物理视频中黄色的字,c#写程序去掉
先看一下效果:(还有改进的余地) 写了个程序消除杨振宁大学物理中黄色的字 我的方法是笨方法,也比较刻板。 1,首先想到,把屏幕打印下来。c#提供了这样一个函数: Bitmap bmp new Bitmap(640, 48…...
uni-app 设置缓存过期时间【跨端开发系列】
🔗 uniapp 跨端开发系列文章:🎀🎀🎀 uni-app 组成和跨端原理 【跨端开发系列】 uni-app 各端差异注意事项 【跨端开发系列】uni-app 离线本地存储方案 【跨端开发系列】uni-app UI库、框架、组件选型指南 【跨端开…...
微信小程序base64图片与临时路径互相转换
1、base64图片转临时路径 /*** 将base64图片转临时路径* param {*} dataurl* param {*} filename* returns*/base64ImgToFile(dataurl, filename "file") {const base64 dataurl; // base64码const time new Date().getTime();const imgPath wx.env.USER_DATA_P…...
蓝桥杯刷题——day2
蓝桥杯刷题——day2 题目一题干题目解析代码 题目二题干解题思路代码 题目一 题干 三步问题。有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶或3阶。实现一种方法,计算小孩有多少种上楼梯的方式。结果可能很大,你需要…...
5.删除链表的倒数第N个节点
19.删除链表的倒数第N个节点 题目: 19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode) 分析: 要删除倒数第几个节点,那么我们需要怎么做呢?我们需要定义两个指针,快指针和慢指针,…...
自己总结:selenium高阶知识
全篇大概10000字(含代码),建议阅读时间30min 一、等待机制 如果有一些内容是通过Ajax加载的内容,那就需要等待内容加载完毕才能进行下一步操作。 为了避免人为操作等待,会遇到的问题, selenium将等待转换…...
前端怎么预览pdf
1.背景 后台返回了一个在线的pdf地址,需要我这边去做一个pdf的预览(需求1),并且支持配置是否可以下载(需求2),需要在当前页就能预览(需求3)。之前我写过一篇预览pdf的文…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...
