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

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

二值化,就是将图像从彩色或灰度模式转换为只有两种颜色(通常是黑色和白色)的模式。这个过程的本质是设定一个阈值 (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.dtcms.com/a/359775.html

相关文章:

  • 如何重置SVN被保存的用户名和密码
  • 基于路测点云标注生成OpenDrive地图的全流程解析
  • TI-92 Plus计算器:函数图像功能介绍
  • ros2bag_py的api小结、丢帧问题对策
  • 第四十九天(springboot模版注入ThymeleafFreemarkerVelocity)
  • 飞牛NAS上部署Markdown文稿编辑器,阅读.md文件同时还可以跨平台访问!
  • 根据Excel数据表快速创建Word表格(标签)
  • JavaScript中的XMLHttpRequest对象分析
  • Docker 存储原理精要
  • s[:] = reversed(s) 和 s = reversed(s)的区别
  • Blender建模:对于模型布线的一些思考
  • FPGA设计杂谈之七:异步复位为何是Recovery/Removal分析?
  • 浅谈 SQL 窗口函数:ROW_NUMBER() 与聚合函数的妙用
  • 深入解析数据结构之单链表
  • 人工智能加速漏洞利用,15分钟即可完成概念验证?
  • 网络:相比于HTTP,HTTPS协议到底安全在哪?
  • go 开发环境配置 air + dlv debug 踩坑之旅
  • AI基础学习周报十一
  • 大模型——利用RAG构建智能问答平台实战
  • 图像描述编辑器 (Image Caption Editor)
  • 文字的力量:Qwen-Image如何让AI真正“读懂”中文之美
  • HTTPS -> HTTP 引起的 307 状态码与HSTS
  • ans.1中的对象标识符OBJECT_IDENTIFIER----OID
  • 【开题答辩全过程】以 基于springboot的垃圾分类管理系统为例,包含答辩的问题和答案
  • 力扣热题100:合并区间详解(Java实现)(56)
  • 历史数据分析——寒武纪
  • Android开发-活动页面
  • 20.28 《4bit量化模型预处理揭秘:如何节省75%显存高效微调LLM?》
  • leetcode-hot-100(堆)
  • 金融学-货币理论