计算机视觉(四):二值化

二值化,就是将图像从彩色或灰度模式转换为只有两种颜色(通常是黑色和白色)的模式。这个过程的本质是设定一个阈值 (Threshold),将图像中所有像素的灰度值与这个阈值进行比较。

基本原理

二值化的核心原理非常简单:

  1. 灰度化:如果原始图像是彩色的,首先需要将其转换为灰度图像。这是因为彩色图像有三个通道(红、绿、蓝),而灰度图像只有一个灰度通道,每个像素的值代表其亮度,从 0(最黑)到 255(最白)。
  2. 设定阈值:选择一个介于 0 到 255 之间的数值作为阈值。这个阈值是二值化成功的关键。
  3. 像素比较与转换:遍历图像中的每一个像素,执行以下操作:
    • 如果像素的灰度值大于设定的阈值,就将其灰度值设置为一个固定值(通常是 255,代表白色)。
    • 如果像素的灰度值小于或等于设定的阈值,就将其灰度值设置为另一个固定值(通常是 0,代表黑色)。

经过上述处理后,图像中的所有像素都只剩下两种可能的值:0 和 255,从而得到了一个黑白分明的二值化图像。

为什么要进行二值化?

二值化是许多图像处理和计算机视觉任务中的一个重要预处理步骤。它之所以重要,主要有以下几个原因:

  • 简化图像数据:将图像从多级灰度简化为黑白两色,极大地减少了数据量和处理的复杂性。这使得后续的算法(如边缘检测、轮廓提取)可以更快、更高效地运行。
  • 突出目标:通过合适的阈值,可以有效地将图像中的前景目标(如文字、物体)从背景中分离出来,使其更加突出和易于识别。
  • 便于分析和识别:在光学字符识别(OCR)、条形码识别、医学图像分析等领域,二值化是必不可少的步骤。它能帮助算法更准确地识别出字符或病变区域。

如何选择合适的阈值?

选择阈值是二值化的核心挑战。错误的阈值会导致信息丢失或引入噪声。根据不同的应用场景,选择阈值的方法主要分为以下两类:

  1. 全局阈值(Global Thresholding)
    • 概念:对整张图像使用同一个固定的阈值。
    • 方法
      • 手动设置:根据经验或对图像的初步分析来设定一个固定的值。
      • 自动计算:通过算法自动寻找一个最优的阈值,例如大津法(Otsu’s method)。大津法的基本思想是找到一个阈值,使得前景和背景的方差最大化,从而实现最佳的分离效果。
    • 局限性:当图像的光照不均匀时,全局阈值效果会很差。例如,如果图像左侧很亮而右侧很暗,一个固定的阈值就无法同时正确地分离两边的目标。
  2. 局部阈值(Local/Adaptive Thresholding)
    • 概念:将图像分割成许多小的区域,对每个小区域分别计算并应用不同的阈值。
    • 方法
      • 均值法(Mean):计算每个小区域内的像素平均值作为该区域的阈值。
      • 高斯法(Gaussian):在计算均值时,为中心像素附近的像素赋予更高的权重,从而得到一个加权平均值作为阈值。
    • 优势:这种方法能很好地处理光照不均或背景复杂的情况,因为它能够根据局部环境自动调整阈值。

灰度图

灰度图的本质

  • 单通道:彩色图像通常有三个颜色通道(红、绿、蓝,即 RGB),每个像素由这三个通道的值组合而成,可以表示数百万种颜色。而灰度图只有一个通道,每个像素的值只代表其亮度灰度级别
  • 0-255 的数值:在 8 位灰度图中,每个像素的取值范围通常是 0 到 255。
    • 0 代表最黑。
    • 255 代表最白。
    • 0 到 255 之间的值则代表不同深浅的灰色,值越大,颜色越亮。
  • 黑白过渡:与只有纯黑和纯白的二值化图像不同,灰度图能够平滑地表现出从黑到白的各种过渡,保留了图像的更多细节信息。

为什么需要灰度图?

将彩色图转换为灰度图是许多图像处理任务中的一个重要步骤,主要有以下几个原因:

  1. 简化数据:灰度图的数据量比彩色图小得多。彩色图需要三个字节(RGB)来存储一个像素,而灰度图只需要一个字节。这可以大大减少存储空间和处理时间。
  2. 突出亮度信息:在许多视觉任务中,例如边缘检测、轮廓识别、物体追踪等,算法主要依赖于图像的亮度或明暗变化。将图像转换为灰度图可以去除不必要的颜色信息,使算法能更专注于分析亮度差异,从而提高效率和准确性。
  3. 预处理步骤:在进行二值化、直方图均衡化等操作之前,通常需要先将图像转换为灰度图。

如何从彩色图得到灰度图?

将一张彩色图片转换为灰度图,最常见的方法是根据人眼对不同颜色的敏感度,对 RGB 三个通道的值进行加权平均

一个常用的转换公式是:

灰度值=0.299×红色值+0.587×绿色值+0.114×蓝色值

这个公式反映了人眼对绿色最敏感,其次是红色,对蓝色最不敏感。OpenCV 等库在进行彩色到灰度转换时,通常会采用类似的加权平均方法。

如果是YUV 转换为灰度图,由于 Y 分量本身就直接代表了图像的亮度信息,而灰度图的本质就是亮度图,因此,从 YUV 转换为灰度图只需要提取 Y 分量即可。

OpenCV实现YUV到灰度图的转换

import cv2
import numpy as np# 1. 加载一张彩色图像 (OpenCV默认以 BGR 格式读取)
bgr_img = cv2.imread('your_image_path.jpg')# 检查图像是否成功加载
if bgr_img is None:print("Error: Could not read the image.")
else:# 2. 将 BGR 图像转换为 YUV 格式# OpenCV 使用 YUV 而非 YCbCr,但原理相同yuv_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2YUV)# 3. 提取 Y 分量(亮度通道),作为灰度图# Y 分量是 YUV 图像的第一个通道gray_img = yuv_img[:,:,0]# 4. 显示原始彩色图像和生成的灰度图像cv2.imshow('Original BGR Image', bgr_img)cv2.imshow('Gray Image from Y Channel', gray_img)# 等待按键,然后关闭所有窗口cv2.waitKey(0)cv2.destroyAllWindows()

opencv实现二值化

cv2.threshold() 函数

ret, dst = cv2.threshold(src, thresh, maxval, type)

参数解释:

  • src: 原始图像,必须是灰度图
  • thresh: 设定的阈值
  • maxval: 当像素值超过(或低于)阈值时,所赋予的最大值。通常是 255。
  • type: 值的类型,决定了如何应用阈值。这是最关键的参数,常用的类型包括:
    • cv2.THRESH_BINARY: 最基础的二值化。如果像素值大于 thresh,则设置为 maxval;否则设置为 0。
    • cv2.THRESH_BINARY_INV: 与 THRESH_BINARY 相反。如果像素值大于 thresh,则设置为 0;否则设置为 maxval
    • cv2.THRESH_TRUNC: 截断。如果像素值大于 thresh,则设置为 thresh;否则保持不变。
    • cv2.THRESH_TOZERO: 如果像素值大于 thresh,则保持不变;否则设置为 0。
    • cv2.THRESH_TOZERO_INV: 与 THRESH_TOZERO 相反。如果像素值大于 thresh,则设置为 0;否则保持不变。

返回值:

  • ret: 设定的阈值。当使用 Otsu’s 或 Triangle 方法时,返回的是自动计算出的阈值。
  • dst: 二值化后的图像

实现基础二值化

import cv2
import numpy as np# 1. 加载图像并转换为灰度图
img = cv2.imread('your_image_path.jpg', cv2.IMREAD_GRAYSCALE)# 检查图像是否成功加载
if img is None:print("Error: Could not read the image.")
else:# 2. 设定阈值并进行二值化处理# 设定阈值为127,最大值为255ret, binary_img = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)# 打印返回的阈值(这里会是127)print(f"Threshold value returned: {ret}")# 3. 显示原始图像和二值化后的图像cv2.imshow('Original Grayscale Image', img)cv2.imshow('Binary Image', binary_img)# 等待按键,然后关闭所有窗口cv2.waitKey(0)cv2.destroyAllWindows()

使用 Otsu’s 方法自动寻找阈值

import cv2
import numpy as np# 1. 加载图像并转换为灰度图
img = cv2.imread('your_image_path.jpg', cv2.IMREAD_GRAYSCALE)if img is None:print("Error: Could not read the image.")
else:# 2. 使用 Otsu's 方法进行自动二值化# 注意:这里阈值参数传入 0,类型与 cv2.THRESH_OTSU 按位或ret, binary_otsu = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# 打印 Otsu's 算法自动计算出的阈值print(f"Otsu's threshold value: {ret}")# 3. 显示图像cv2.imshow('Original Grayscale Image', img)cv2.imshow('Otsu\'s Binary Image', binary_otsu)cv2.waitKey(0)cv2.destroyAllWindows()

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

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

相关文章

(二)设计模式(Command)

文章目录项目地址一、设计模式1.1 Command Design1. 创建命令接口2. 创建支付的Command类3. CommandScheduler4. 使用1.2 Chain of Responsibility1. 接口创建2. 审批人3. 发起审批1.3 State Pattern1. 创建简单的状态机定义动作和状态状态机使用状态机1.x Iterator1.x Observe…

现代C++性能陷阱:std::function的成本、异常处理的真实开销

1. std::function 的成本 std::function 是一个通用的、类型擦除的函数包装器,它非常方便,可以存储和调用任何可调用对象(函数、lambda、函数对象、bind表达式等)。然而,这种灵活性是有代价的。 主要成本来源&#xff…

基于Spark的白酒行业数据分析与可视化系统的设计与实现

文章目录有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主项目介绍一、项目背景与研究意义二、系统整体架构三、系统功能设计四、应用场景与价值五、项目特色与创新点六、总结与展望每文一语有需要本项目的代码或文档以及全部资源,或者部…

织梦会员中心模板调用某个栏目名和栏目下文档的办法

大家在用到织梦dedecms时候,需要在会员中心模板调用栏目的名称和链接,还有某个栏目下的文档要怎么操作呢? 我们都知道,在会员中心模板,直接用dede:type或者dede:arclist标签是不行的,在会员中心调用只能用p…

区块链的法律定位:技术、工具还是资产?

高鹏律师首席数据官,数字经济团队创作AI辅助当我们谈论区块链时,我们在谈论什么?是那串不可篡改的哈希值,是去中心化的信仰图腾,还是藏在代码背后的权利密码?今天,我们不聊技术迭代的炫酷&#…

LeetCode每日一题,2025-8-31

dfs搜索解数独,重点是如何判断当前这位置的board[x][y]是否可以填数字num public class T37 {public static void main(String[] args) {char[][] board new char[][]{{5, 3, ., ., 7, ., ., ., .},{6, ., ., 1, 9, 5, ., ., .},{., 9, 8, ., ., ., ., 6, .},{8, …

Linux 进程信号学习笔记:从概念到实操

一、Linux 信号基本概念1.1 生活角度理解信号我们可以把进程比作等待快递的人,信号就像快递:识别信号:就像我们知道快递来了该 怎么处理,进程对信号的识别是内核程序员预先编写的内置特性,即使信号没产生,进…

解决多种类潮湿敏感元器件的多温度、多时长的排潮烘干

铠德科技ESD烘箱针对复杂电路产品的排潮烘干需求,可通过以下技术路径实现多品类元器件的高效兼容处理:多温区独立控制系统采用蜂窝式加热模块阵列,每个0.6m独立温区可设置1℃精度支持同时运行3种不同温度曲线(典型值:8…

obdumper和obloader迁移OceanBase业务库(一):实施手册

obdumper和obloader迁移OceanBase业务库(一):实施手册导出前准备全库(模式)数据导出全库(模式)数据导入导入后检查环境信息:OceanBase v4.3.5单机部署,MySQL租户OBDUMPER…

SQLSugar 快速入门:从基础到实战查询与使用指南

目录 ​编辑 一、SQLSugar 简介 二、SQLSugar 环境搭建 2.1 安装 SQLSugar 2.1.1 通过 Visual Studio NuGet 图形化界面安装 2.1.2 通过 NuGet 命令行安装 2.2 引用 SQLSugar 命名空间 三、SQLSugar 核心初始化配置 3.1 基础初始化(非 IOC 模式&#xff09…

Python与Rust语法对比详解:从入门到精通

Python与Rust语法对比详解:从入门到精通 前言 Python和Rust作为当今最受关注的编程语言,分别代表了动态类型和静态类型语言的典型特征。本文将从语法层面深入对比这两种语言,帮助开发者理解它们的设计理念和使用场景。1. 基础语法结构 1.1 He…

视频加水印_带gif 加动态水印 gif水印 视频浮动水印

如果你有一个视频,你想给它加一个水印,让水印浮动,而且加的还是 GIF 动态图片水印,那么你可以使用这个工具。首先把你的两个文件拖进来,然后点击第三个按钮。加好了,打开看一下,我们看到这个水印…

C# 字符和字符串

原文:C# 字符和字符串_w3cschool 请勿将文章标记为付费!!!!! C#字符和字符串 C#的 char 类型别名 System.Char 类型表示 Unicode 字符。 在单引号中指定char字面值: …

IntelliJ IDEA 反编译JAR包记录

本文记录了使用 IntelliJ IDEA 内置反编译工具对 JAR 包进行反编译的详细步骤,方便日后快速参考和使用。 🛠️ 工具准备 反编译工具使用的是 IntelliJ IDEA 内置的 Java 反编译器,无需额外安装其他工具。 工具路径: /Applications…

KingbaseES JDBC 驱动详解:连接、配置与最佳实践

目录KingbaseES JDBC 驱动详解:连接、配置与最佳实践引言一、JDBC 基础与 KingbaseES 实现1.1 JDBC 技术概述1.2 KingbaseES JDBC 驱动特点二、环境配置与驱动获取2.1 驱动包选择与依赖管理2.2 国密算法支持2.3 驱动版本信息获取三、数据库连接管理3.1 使用 DriverM…

破解 Aspose.Words 24.12,跳过 License 校验,实现 HTML 向 Word/PDF 的转换,附带 Demo。

说明 在Java生态中处理Office文档时,开发人员常面临格式兼容性和功能完整性的挑战。商业组件Aspose以其卓越的文档处理能力成为企业级解决方案之一,支持Word、Excel、PDF等多种格式的精准转换与操作。 请勿用于商业用途,若侵权请联系我。 参考…

php连接rabbitmq例子

首先确保安装好了Rabbitmq服务器。1.新建一个空白php项目&#xff0c;安装php客户端库&#xff1a;composer require php-amqplib/php-amqplib2.生产者然后添加生产者代码 (producer.php)<?php require_once __DIR__ . /vendor/autoload.php;use PhpAmqpLib\Connection\AMQ…

Docker Swarm vs Kubernetes vs Nomad:容器编排方案对比与选型建议

Docker Swarm vs Kubernetes vs Nomad&#xff1a;容器编排方案对比与选型建议 在微服务和云原生时代&#xff0c;容器编排成为支持大规模容器化应用的关键技术。本文将从问题背景、方案对比、优缺点分析、选型建议以及实际应用效果验证五个方面&#xff0c;对Docker Swarm、Ku…

似然函数对数似然函数负对数似然函数

目录1. 似然函数的定义2. 对数似然函数的定义3. 负对数似然函数的定义4. 负对数似然函数的优化5. 具体应用示例5.1 逻辑回归中的负对数似然函数5.2 优化逻辑回归的负对数似然函数1. 似然函数的定义 似然函数L(θ∣X)L(\theta | X)L(θ∣X)是在给定参数θ\thetaθ 下&#xff0…

鸿蒙地址选择库(ArkTs UI)

功能点&#xff1a;支持三级联动、点击确认返回省市区code及name&#xff08;安心&#xff09;、布局可以高度自定义 实现&#xff1a;TextPicker读取本地json&#xff08;也可用第三方的json 不过需要自行调整了&#xff09; 先上图吧、废话下面再说&#xff1a; 凑和看吧、…