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

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

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

相关文章:

  • MySQL面试集合
  • 【C++ 】STL详解(六)—手撸一个属于你的 list!
  • 力扣热题100:合并区间详解(Java实现)(56)
  • 在SAP系统中,如何查询已经被打上了删除标记的生产订单?
  • 数据结构(04)—— 栈和队列
  • [每周一更]-(第158期):构建高性能数据库:MySQL 与 PostgreSQL 系统化问题管理与优化指南
  • 【lua】元表、元方法 详解及应用
  • 【LeetCode_27】移除元素
  • Ubuntu中通过SSH克隆Windows的远程Git仓库(局域网中挺有用)
  • 对于牛客网—语言学习篇—编程初学者入门训练—复合类型:二维数组较简单题目的解析
  • Unity核心概念①
  • 准备机试--图【y总版】[重要]【最短路】
  • 三重积分的对称性
  • shell编程-核心变量知识
  • 面试专栏
  • Agent实战教程:LangGraph结构化输出详解,让智能体返回格式化数据
  • 第N个丑数
  • 文件夹和文件一键加密,保护你的隐私
  • CRM、ERP、HRP系统有啥区别?
  • 本地运行 Ollama 与 DeepSeek R1 1.5B,并结合 Open WebUI 测试
  • 安卓编程 之 线性布局
  • 数组去重【JavaScript】
  • 基于 MyBatis-Plus 拦截器实现锁定特殊数据(二)
  • kmp 算法
  • 42-Ansible-Inventory
  • 模式组合应用-组合模式
  • SpringAI应用开发面试剧本与技术知识全解析:RAG、向量数据库、多租户与企业落地场景
  • DbVisualizer:一款功能强大的通用数据库管理开发工具
  • 1.8 Memory
  • Python 入门 Swin Transformer-T:原理、作用与代码实践