图像处理:阈值与形态学实战指南

目录

图像阈值

[一、cv2.threshold 函数整体说明](#一、cv2.threshold 函数整体说明)

参数含义(博客标准表述)

二、五种阈值类型

[1️⃣ cv2.THRESH_BINARY(最常用)](#1️⃣ cv2.THRESH_BINARY(最常用))

[2️⃣ cv2.THRESH_BINARY_INV(反二值化)](#2️⃣ cv2.THRESH_BINARY_INV(反二值化))

[3️⃣ cv2.THRESH_TRUNC(截断阈值)](#3️⃣ cv2.THRESH_TRUNC(截断阈值))

[4️⃣ cv2.THRESH_TOZERO(阈值以下清零)](#4️⃣ cv2.THRESH_TOZERO(阈值以下清零))

[5️⃣ cv2.THRESH_TOZERO_INV(TOZERO 的反向)](#5️⃣ cv2.THRESH_TOZERO_INV(TOZERO 的反向))

​编辑

示例最常见的二值化处理(THRESH_BINARY)

图像模糊(平滑处理)

一、均值滤波

[1 .均值滤波原理](#1 .均值滤波原理)

[2. 示例代码](#2. 示例代码)

二、方框滤波

[1 .方框滤波原理](#1 .方框滤波原理)

[2 .归一化与否的区别](#2 .归一化与否的区别)

三、高斯滤波与中值滤波

高斯滤波的基本思想

高斯滤波的原理说明

[OpenCV 实现示例](#OpenCV 实现示例)

参数说明

四、中值滤波

中值滤波的基本思想

中值滤波的原理说明

[OpenCV 实现示例](#OpenCV 实现示例)

参数说明

形态变换

腐蚀

腐蚀的数学原理

[1️⃣ 结构元素(Structuring Element)](#1️⃣ 结构元素(Structuring Element))

[2️⃣ 二值腐蚀的规则](#2️⃣ 二值腐蚀的规则)

灰度腐蚀的规则

[OpenCV 中的腐蚀实现](#OpenCV 中的腐蚀实现)

示例代码

膨胀(腐蚀的逆操作)

[cv2.dilate() 函数重点讲解(参数与腐蚀相同)](#cv2.dilate() 函数重点讲解(参数与腐蚀相同))

[1️⃣ src:输入图像](#1️⃣ src:输入图像)

[2️⃣ kernel:结构元素(决定"怎么膨胀")](#2️⃣ kernel:结构元素(决定“怎么膨胀”))

[3️⃣ iterations:膨胀次数(决定"膨胀几轮")](#3️⃣ iterations:膨胀次数(决定“膨胀几轮”))

开运算与闭运算

核心函数:cv2.morphologyEx

参数逐个解释

[(1)src ------ 输入图像](#(1)src —— 输入图像)

[(2)op ------ 形态学操作类型](#(2)op —— 形态学操作类型)

[(3)kernel ------ 结构元素](#(3)kernel —— 结构元素)

[(4)iterations ------ 重复次数(默认 1)](#(4)iterations —— 重复次数(默认 1))

形态学梯度运算

一、梯度运算是什么?一句话

二、它为什么能提取边缘?(直观解释)

标准示例代码

礼帽(Top-hat)与黑帽(Black-hat)运算

一、一句话先记住

二、礼帽(Top-hat)运算

[1️⃣ 定义(核心公式)](#1️⃣ 定义(核心公式))

[OpenCV 示例代码](#OpenCV 示例代码)

三、黑帽(Black-hat)运算

[1️⃣ 定义(核心公式)](#1️⃣ 定义(核心公式))

[OpenCV 示例代码(常用写法)](#OpenCV 示例代码(常用写法))

函数:cv2.morphologyEx

[op 参数可选值说明](#op 参数可选值说明)


图像阈值

阈值的作用是:根据像素强度大小,将图像中的信息进行"区分、简化和分离"。

更直白一点:

把"有用的"和"没那么重要的"像素分开。

一、cv2.threshold 函数整体说明

参数含义(博客标准表述)

  • src :输入图像

    只能是单通道图像,通常为灰度图

  • dst :输出图像

    经过阈值处理后的结果

  • thresh :阈值

    用于判断像素"是否满足条件"的分界值

  • maxval :最大值

    当像素满足条件时,被赋予的值(常用 255)

  • type :阈值处理类型

    决定"满足阈值"和"不满足阈值"时像素如何变化

  • ret :实际使用的阈值

    普通阈值时 ret == thresh(在自适应 / OTSU 时才有特殊意义)

二、五种阈值类型

1️⃣ cv2.THRESH_BINARY(最常用)

规则:

bash 复制代码
像素值 > thresh  →  maxval
像素值 ≤ thresh →  0

一句话理解:

超过阈值的变成白色,其余变成黑色

2️⃣ cv2.THRESH_BINARY_INV(反二值化)

规则:

bash 复制代码
像素值 > thresh  →  0
像素值 ≤ thresh →  maxval

一句话理解:

和 BINARY 完全相反,黑白对调

3️⃣ cv2.THRESH_TRUNC(截断阈值)

规则:

bash 复制代码
像素值 > thresh  →  thresh
像素值 ≤ thresh →  原值不变

一句话理解:

把亮的"压下来",暗的保持不变

4️⃣ cv2.THRESH_TOZERO(阈值以下清零)

规则:

bash 复制代码
像素值 > thresh  →  原值不变
像素值 ≤ thresh →  0

一句话理解:

阈值以下的像素被变成黑色(0)

5️⃣ cv2.THRESH_TOZERO_INV(TOZERO 的反向)

规则:

bash 复制代码
像素值 > thresh  →  0
像素值 ≤ thresh →  原值不变

📌 特点

TOZERO 完全相反,用得相对少

示例最常见的二值化处理(THRESH_BINARY

python 复制代码
import cv2

# 读取图像并转换为灰度图
img = cv2.imread('test.png', cv2.IMREAD_GRAYSCALE)

# 固定阈值二值化
ret, binary = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

# 显示结果
cv2.imshow('Original', img)
cv2.imshow('Binary', binary)
cv2.waitKey(0)
cv2.destroyAllWindows()

阈值处理要求输入图像为单通道,因此通常先读取或转换为灰度图。

python 复制代码
ret, binary = cv2.threshold(...)
  • retret 表示函数实际采用的阈值

  • binary :阈值处理后的图像结果,就是输出图像 dst

图像模糊(平滑处理)

平滑滤波主要用于降低图像中的随机噪声。其基本思想是利用邻域像素的信息,对当前像素进行重新计算,从而减弱局部的剧烈变化。

一、均值滤波

1 .均值滤波原理

均值滤波是一种典型的线性平滑滤波方法,其核心思想是:
用邻域像素的平均值替换当前像素的值。

以 3×3 窗口为例,滤波器以当前像素为中心,选取周围 9 个像素,计算它们的平均值,并将该平均值作为中心像素的新值。

2. 示例代码

python 复制代码
import cv2

img = cv2.imread('lenaNoise.png')

blur = cv2.blur(img, (3, 3))

cv2.imshow('blur', blur)
cv2.waitKey(0)
cv2.destroyAllWindows()

二、方框滤波

1 .方框滤波原理

方框滤波与均值滤波本质相同,都是在固定大小的邻域内对像素进行处理。其不同之处在于是否对计算结果进行归一化

python 复制代码
box = cv2.boxFilter(img, -1, (3, 3), normalize=True)

2 .归一化与否的区别

  • normalize=True

    对邻域内像素求和后再除以像素个数,结果为平均值,效果等价于均值滤波。

  • normalize=False

    仅对邻域像素进行求和,不进行平均。此时中心像素的新值等于邻域像素值的累加结果

从数学角度看:

  • 均值滤波 = 求和 + 归一化

  • 非归一化方框滤波 = 直接求和

三、高斯滤波与中值滤波

高斯滤波的基本思想

高斯滤波是一种加权平均滤波 。与均值滤波中"所有像素权重相同"不同,高斯滤波遵循高斯分布规律

距离中心像素越近,权重越大;距离越远,权重越小。

因此,中心像素对最终结果的影响最大,边缘像素影响较小。

高斯滤波的原理说明

在高斯滤波中,邻域内像素值会与一个高斯权重矩阵相乘,再进行加权求和,最终得到中心像素的新值。其数学模型可以表示为:

OpenCV 实现示例

python 复制代码
import cv2

img = cv2.imread('lenaNoise.png')

gaussian = cv2.GaussianBlur(img, (3, 3), 0)

cv2.imshow('gaussian', gaussian)
cv2.waitKey(0)
cv2.destroyAllWindows()
参数说明
python 复制代码
cv2.GaussianBlur(src, ksize, sigmaX)
  • src:输入图像

  • ksize:高斯核大小,通常为奇数,如 (3,3)、(5,5),以当前像素为中心,取多大范围的邻域参与加权计算。

  • sigmaX:X 方向的标准差

    • 为 0 时,由 OpenCV 根据核大小自动计算,根据 ksize 自动计算一个合适的 sigmaX

    • 离中心像素越远,权重下降得有多快

四、中值滤波

中值滤波的基本思想

中值滤波是一种非线性滤波方法

其核心思想是:

用邻域像素的"中位数"替换当前像素值。

中值滤波的原理说明

以 3×3 窗口为例:

  1. 取当前像素周围的 9 个像素值

  2. 对这 9 个数进行排序

  3. 取排序后的中间值

  4. 用该中位数替换中心像素

📌 与均值不同,中值滤波不会受到极端噪声值的强烈影响

OpenCV 实现示例

python 复制代码
import cv2

img = cv2.imread('lenaNoise.png')

median = cv2.medianBlur(img, 3)

cv2.imshow('median', median)
cv2.waitKey(0)
cv2.destroyAllWindows()
参数说明
python 复制代码
cv2.medianBlur(src, ksize)
  • src:输入图像

  • ksize:滤波窗口大小**(必须是奇数)**

滤波方法 类型 特点 适用场景
均值滤波 线性 简单平均,易模糊边缘 噪声较弱
高斯滤波 线性 加权平均,平滑自然 高斯噪声
中值滤波 非线性 抗极端值,保边缘 椒盐噪声

形态变换

腐蚀

形态学腐蚀(Erosion)是数学形态学中的一种基本操作,主要用于缩小前景区域消除小的白色噪点 以及分离相互连接的目标 。腐蚀操作通常应用于二值图像,也可用于灰度图像。

可以把腐蚀理解为:

用一个结构元素在图像上"扫描",
只要结构元素覆盖范围内存在不满足条件的像素,
当前像素就会被"削弱"。

在二值图像中,腐蚀的效果表现为:

  • 白色前景区域 变小

  • 黑色背景区域 变大

  • 细小的白色噪声被去除

腐蚀的数学原理

1️⃣ 结构元素(Structuring Element)

腐蚀操作需要一个结构元素(kernel),常见形状有:

  • 矩形

  • 十字形

  • 椭圆形

例如一个 3×3 的结构元素:

bash 复制代码
1  1  1
1  1  1
1  1  1
2️⃣ 二值腐蚀的规则

对于二值图像:

只有当结构元素覆盖的区域内,所有像素都为前景(白色)时,中心像素才保持为白色;否则变为黑色。

换句话说:只要邻域中有一个黑点 → 中心像素变黑

以 3×3 结构元素为例,对当前中心像素:

  1. 将结构元素中心对准当前像素

  2. 检查结构元素覆盖的邻域

  3. 若邻域内存在黑色像素

    → 当前像素设为黑色

  4. 若邻域内全部为白色

    → 当前像素保持白色

灰度腐蚀的规则

在灰度图像中,腐蚀的定义为:

取结构元素覆盖区域内的最小灰度值,作为中心像素的新值。

📌 这可以理解为:

  • "亮区域被削弱"

  • "暗区域被扩散"

OpenCV 中的腐蚀实现

python 复制代码
cv2.erode(src, kernel, iterations=1)

参数说明:

  • src:输入图像(通常为二值图像)

  • kernel:结构元素,决定了算法在进行腐蚀或膨胀时,当前像素周围哪些像素会参与判断

  • iterations:腐蚀次数

示例代码
python 复制代码
import cv2
import numpy as np

img = cv2.imread('binary.png', 0)

kernel = np.ones((3, 3), np.uint8)

eroded = cv2.erode(img, kernel, iterations=1)

cv2.imshow('eroded', eroded)
cv2.waitKey(0)
cv2.destroyAllWindows()

iterations 的作用

  • iterations = 1

    → 腐蚀一次,边缘缩小一圈

  • iterations > 1

    → 多次腐蚀,前景区域进一步缩小

膨胀(腐蚀的逆操作)

膨胀 = 让白色前景"变大",让目标向外扩张。

只要结构元素覆盖范围内"有白色",
中心像素就会变成白色。

  • 腐蚀:白的变小

  • 膨胀:白的变大

操作 判断规则
腐蚀 只要有黑 → 变黑
膨胀 只要有白 → 变白

cv2.dilate() 函数重点讲解(参数与腐蚀相同)

python 复制代码
dst = cv2.dilate(src, kernel, iterations=1)
1️⃣ src:输入图像
  • 通常是 二值图像(0/255),也可以是灰度图或彩色图。

  • 形态学最常见流程是:
    灰度 → 二值化 → 膨胀/腐蚀

📌 初学建议:先用二值图理解效果最直观。

2️⃣ kernel:结构元素(决定"怎么膨胀")

kernel 是一个小矩阵,用来规定:

  • 膨胀时"看多大范围"

  • 朝哪些方向扩张

  • 扩张的形状

python 复制代码
kernel = np.ones((3,3), np.uint8)

含义:

  • 使用 3×3 矩形结构元素

  • 以中心为主,向四周扩一圈(效果比较均匀)

常见结构元素写法:

python 复制代码
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))   # 矩形
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3,3))  # 十字
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3)) # 椭圆
3️⃣ iterations:膨胀次数(决定"膨胀几轮")
python 复制代码
dilate = cv2.dilate(src, kernel, iterations=3)

含义:

  • 膨胀执行 3 次

  • 每一次都是在上一次结果基础上继续膨胀

📌 规律很简单:

iterations 越大,白色区域越大,连接效果越明显,但细节越容易糊掉。

开运算与闭运算

核心函数:cv2.morphologyEx

python 复制代码
dst = cv2.morphologyEx(src, op, kernel, iterations=1)
参数逐个解释
(1)src ------ 输入图像
python 复制代码
img = cv2.imread('dige.png')
  • 一般是 二值图像

  • 形态学操作对二值图最直观

(2)op ------ 形态学操作类型

这是开运算 / 闭运算的核心区别

运算 顺序 主要作用
开运算 腐蚀 → 膨胀 去白噪点
闭运算 膨胀 → 腐蚀 填黑洞、连断裂
(3)kernel ------ 结构元素
python 复制代码
kernel = np.ones((5,5), np.uint8)
  • 决定:

    • 看多大范围

    • 形态变化"有多狠"

  • 5×5 比 3×3 效果更明显

(4)iterations ------ 重复次数(默认 1)
  • 每多一次,相当于再做一轮形态学操作

cv2.morphologyEx() 是 OpenCV 中用于执行高级形态学操作的函数。通过设置不同的操作类型参数,可以实现开运算和闭运算。其中,**开运算由腐蚀和膨胀组成,常用于去除小的白色噪点;闭运算由膨胀和腐蚀组成,常用于填补目标内部的小黑洞或连接断裂区域。**结构元素的大小和形状会直接影响形态学处理的效果。

形态学梯度运算

一、梯度运算是什么?一句话

形态学梯度 = 膨胀结果 − 腐蚀结果

得到的主要是目标的边缘轮廓(边界区域会被突出)。

二、它为什么能提取边缘?(直观解释)

  • 膨胀:白色区域向外扩张(边界往外推)

  • 腐蚀:白色区域向内收缩(边界往里缩)

把"外扩后的图"减去"内缩后的图":

只剩下"外边界到内边界之间的一圈差值"

这圈差值就是边缘带

所以梯度结果看起来像"描边"。

标准示例代码

python 复制代码
import cv2
import numpy as np

# 1. 读取图像并转为灰度
img = cv2.imread('image.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 2. 二值化(可选,但强烈推荐)
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

# 3. 构造结构元素(常用 3x3)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))

# 4. 形态学梯度运算
gradient = cv2.morphologyEx(binary, cv2.MORPH_GRADIENT, kernel)

# 5. 显示结果
cv2.imshow('Binary', binary)
cv2.imshow('Morphological Gradient', gradient)
cv2.waitKey(0)
cv2.destroyAllWindows()

礼帽(Top-hat)与黑帽(Black-hat)运算

这两个其实都是 基于"开运算 / 闭运算"的差分运算,不是全新的形态学操作。

一、一句话先记住

礼帽:提亮的小白结构
黑帽:提暗的小黑结构

二、礼帽(Top-hat)运算

1️⃣ 定义(核心公式)

Top-hat=原图−开运算

也就是:礼帽 = 原图 − (腐蚀 → 膨胀)

把**"被开运算去掉的那部分"**拿出来。

OpenCV 示例代码
python 复制代码
import cv2
import numpy as np

# 读取图像,并以灰度模式加载
# 第二个参数为 0,表示直接读取为单通道灰度图
img = cv2.imread('image.png', 0)

# 构造结构元素(Structuring Element)
# cv2.MORPH_RECT 表示矩形结构元素
# (15, 15) 表示结构元素的大小,决定"多大的亮结构会被提取"
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15, 15))

# 礼帽(Top-hat)运算
# Top-hat = 原图 - 开运算
# 用于提取图像中尺寸较小的亮区域或亮细节
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)

# 显示礼帽运算结果
cv2.imshow('Top-hat', tophat)

# 等待按键,防止窗口一闪而过
cv2.waitKey(0)

# 关闭所有 OpenCV 创建的窗口
cv2.destroyAllWindows()

该示例通过礼帽运算提取图像中尺寸较小的亮结构,结构元素大小决定了被增强亮区域的尺度范围。

三、黑帽(Black-hat)运算

1️⃣ 定义(核心公式)

Black-hat=闭运算−原图

也就是:黑帽 = (膨胀 → 腐蚀) − 原图 ,把"被闭运算填掉的那部分"拿出来。

所以黑帽最终得到的是:

原图中"尺寸较小的暗区域"

OpenCV 示例代码(常用写法)
python 复制代码
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

cv2.imshow('Black-hat', blackhat)
cv2.waitKey(0)
cv2.destroyAllWindows()

函数:cv2.morphologyEx

在数学形态学中,礼帽运算和黑帽运算是基于开运算和闭运算的差分操作,而形态学梯度则是由膨胀和腐蚀的差值构成,并不依赖开运算或闭运算。OpenCV 将上述运算统一封装在 cv2.morphologyEx() 函数中,通过不同的 op 参数进行区分。

python 复制代码
cv2.morphologyEx(src, op, kernel)

其中:

  • src:输入图像(通常为二值图像或灰度图像)

  • op:形态学操作类型

  • kernel:结构元素,用于定义邻域范围和形状

op 参数可选值说明

op 用于指定具体的形态学运算类型,常见取值如下:

  • cv2.MORPH_OPEN,开运算,腐蚀 → 膨胀

  • cv2.MORPH_CLOSE**,**闭运算,膨胀 → 腐蚀

  • cv2.MORPH_GRADIENT,**形态学梯度,**膨胀−腐蚀,提取边界

  • cv2.MORPH_TOPHAT,礼帽**=原图−开运算**

  • cv2.MORPH_BLACKHAT**,黑帽=**闭运算−原图

运算类型 主要作用
开运算(OPEN) 去除小的白色噪点
闭运算(CLOSE) 填补小的黑洞、连接断裂区域
形态学梯度(GRADIENT) 提取目标边界
礼帽(TOPHAT) 提取图像中较小的亮结构
黑帽(BLACKHAT) 提取图像中较小的暗结构

cv2.morphologyEx() 通过不同的 op 参数实现多种形态学组合运算,使得复杂的形态学操作可以通过统一接口完成,既保证了运算顺序的正确性,也提高了代码的简洁性与可读性。

相关推荐
啊阿狸不会拉杆2 小时前
《数字图像处理》实验4-图像复原
图像处理·人工智能·机器学习·计算机视觉·数字图像处理
有Li2 小时前
医学生图像分割的测试时生成增强方法文献速递-医疗影像分割与目标检测最新技术
人工智能·计算机视觉·目标跟踪
AndrewHZ2 小时前
【图像处理基石】光线追踪(Ray Tracing)算法入门
图像处理·人工智能·算法·计算机视觉·计算机图形学·光线追踪·渲染技术
子夜江寒2 小时前
OpenCV 入门:图像与视频的基础操作
python·opencv·音视频
AI即插即用16 小时前
即插即用系列 | TGRS 2025 MGAM:面向遥感微小目标检测的多尺度高斯注意力机制
图像处理·人工智能·深度学习·目标检测·计算机视觉·视觉检测
Fuly102417 小时前
多模态大模型应用技术栈
人工智能·深度学习·计算机视觉
s090713618 小时前
常用FPGA实现的图像处理算法
图像处理·算法·fpga开发
wang_chao11818 小时前
Yolov5训练自定义数据集的步骤
深度学习·yolo·计算机视觉
搞科研的小刘选手19 小时前
【遥感测绘专题会议】第三届遥感、测绘与图像处理国际学术会议(RSMIP 2026)
图像处理·遥感·测绘·学术会议·摄影测量