图像阈值是一种简单、高效的图像分割方法,目的是将图像转换成二值图像。这个过程涉及比较像素值和阈值,根据比较结果来确定每个像素点的状态(前景或背景)。图像阈值在处理二维码、文本识别、物体跟踪等领域中非常有用。本博客旨在简介OpenCV中的阈值处理方法,并提供实现代码,适合初学者学习。
理论介绍:
1. 阈值类型:
阈值化是图像处理中的一个常见步骤,特别是在图像二值化中使用得非常频繁。二值化是指将图像的像素值只保留两个值,常见的处理方法是将其转变为纯黑和纯白,以简化后续的分析。以下是几种常见的阈值化方法,并对它们进行了一些扩充说明:
- 二进制阈值 (Binary Thresholding):这种方法在处理图像时非常直接。你会设定一个阈值,所有高于这个阈值的像素都会变成一个固定的新值,通常设为最大值255(白色),而低于阈值的就变成另一个固定值通常为0(黑色)。这样操作后,图像变为只有黑白两种颜色,这个方法在去除图像噪声或者将感兴趣区域与背景明显分开时非常有用。
- 反二进制阈值 (Inverse Binary Thresholding):与二进制阈值恰好相反,这个方法在像素值高于设定阈值时,会将这些像素点变黑(值为0),而低于阈值的则变白(值为255)。这种方法可以用在背景比目标暗或者在特定情况下希望突出更加明亮区域的场景中。
- 截断阈值 (Truncated Thresholding):在这种模式下,像素值高于阈值时,不是变成最大值,而是直接设定为阈值本身,所以阈值以上部分看起来会是同一亮度。如果原始图像灰度级较高,这种方法能够减少亮度的动态范围。
- 阈值化为零 (Thresholding to Zero):在此方法中,只有当像素值高于阈值时,像素值才会保持不变;如果像素值低于阈值,则会变为零(即变为黑色)。这种方式有助于保持亮度较高的图像区域,而去除其余部分。
- 反阈值化为零 (Inverse Thresholding to Zero):与阈值化为零相比,这里采取相反的策略。低于阈值的像素点保持不变,而高于阈值的点则会被设为零。这种方法有时可以突出比较暗的背景或物体细节。
在实践中,可以根据具体的图像内容和要解决的问题选用合适的阈值化方法。例如,对于简化图像和提取出最有信息的部分,通常可能会选择二进制阈值或反二进制阈值。而对于想要降低亮度动态范围或只关注特定亮度区间的图像,截断阈值可能会更适用。阈值化为零和反阈值化为零则更多用在需要保留某一亮度区域的情况。在OpenCV等图像处理库中,这些阈值化操作有现成的函数可以直接使用,简化了图像预处理的步骤。
2. 自适应阈值:
在不同区域的光照条件不一致的情况下,自适应阈值可以更好地处理图像,它会基于图像上的小区域(邻域)而不是整个图像来计算阈值。
示意图
示意图如下,这是从参考文献1中截取的图片。
放大了看看:
把关键的几个放大看看:
反二值化阈值处理:
截断阈值化处理:
程序展示
使用Python编写程序:
Python程序
具体代码如下:
# -*- coding: utf-8 -*-
"""
Created on Sat Feb 17 21:26:05 2024@author: 李立宗公众号:计算机视觉之光知识星球:计算机视觉之光"""import cv2# 读取图像
image = cv2.imread('lena.bmp', cv2.IMREAD_GRAYSCALE)# 应用全局阈值处理
ret, binary_thresh = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)# 应用自适应阈值处理
adaptive_thresh = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)# 显示原始图像,全局阈值处理结果和自适应阈值处理结果
cv2.imshow('Original Image', image)
cv2.imshow('Binary Threshold', binary_thresh)
cv2.imshow('Adaptive Threshold', adaptive_thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果
可以看到不同的输出结果:
相关知识点
理解并实现OpenCV中的图像平滑技术
OpenCV中的边缘检测技术及实现
OpenCV识别人脸案例实战
参考文献
1、OpenCV轻松入门
李立宗,OpenCV轻松入门,电子工业出版社,2023
2、计算机视觉40例
李立宗,计算机视觉40例,电子工业出版社,2022