OpenCV3
分析图像灰度分布(可视化像素强度分布(plt.hist全局均衡化:简单快速,适合整体低对比度图像自适应均衡化:保留局部特征,计算复杂度较高读取灰度图像(计算原始直方图选择均衡化方法可视化对比结果类别核心内容关键步骤/注意事项原理将歪斜图像转换为规整文档的坐标映射技术需两组坐标:原始图像轮廓点 + 目标矩形点max(w1,w2)和max(h1,h2)坐标点要求必须提供4组非共线点(通常为矩形轮廓)点
课时21:均值化原理_笔记
直方图均衡化
掩码操作
示例
创建方法
使用 np.zeros(img.shape[:2], np.uint8) 创建与图像大小相同的二维零矩阵。
将需要保留的区域设置为 255:mask[100:300, 100:400] = 255。
注意图像大小要保持一致,使用 img.shape 获取原图尺寸。
操作原理
掩码只有两部分组成:0(黑色)和 255(白色)。
通过 cv2.bitwise_and() 执行与操作,保留掩码为 255 的区域。
黑色区域(0 值)会被完全过滤掉,相当于图像截取操作。
效果展示
原始图像:完整的灰度图。
掩码图像:黑白分明的矩形区域。
处理后图像:只保留掩码白色区域的图像内容。
直方图对比:显示原始图像和掩码区域的像素分布差异。
直方图均衡化的基本原理

统计函数cv2.calcHist(images, channels, mask, histSize, ranges)
images:需用中括号包裹,如[img]。channels:灰度图为[0],彩色图可分别统计 BGR 通道[0][1][2]。mask:None表示统计整图,使用掩码可统计特定区域。histSize:BIN 数目,如[256]。ranges:像素值范围,通常为[0,256]。
例题:直方图均衡化
计算步骤
统计各灰度值的像素个数。
计算每个灰度值的概率。
计算累积概率。
映射新灰度值。
示例解析
原始灰度值 50(4 个像素)→ 累积概率 0.25 → 新值 64。
灰度值 128(3 个像素)→ 累积概率 0.4375 → 新值 112。
最终效果
将 “瘦高” 的直方图分布变为 “矮胖” 的均衡分布。
核心思想
通过累积概率函数实现灰度值重新分配,使像素值分布更均匀。
掩码(Mask)原理与操作
| 知识点 | 核心内容 | 操作要点 | 应用示例 |
|---|---|---|---|
| 掩码原理 | 黑白二值矩阵(0/255) | 创建与图像同尺寸的无符号矩阵 目标区域设为255 与原始图像进行按位与操作 |
猫图像局部提取:掩码白色区域保留原图,黑色区域置零 |
直方图均衡化技术
| 实现方法 | 数学原理 | 处理流程 | 效果表现 |
|---|---|---|---|
| 直方图均衡化 | 概率分布映射改善对比度 | 统计各灰度级频率 计算累积分布函数 映射公式:新值=累积概率×255 |
狗图像处理:集中分布的灰度值被拉伸到更广范围 |
掩码实操步骤
# OpenCV掩码实现示例
import cv2
import numpy as np
# 初始化与图像同尺寸的黑色掩码
mask = np.zeros(image.shape[:2], dtype=np.uint8)
# 设置目标区域为白色(255)
cv2.rectangle(mask, (x,y), (x+w,y+h), 255, -1)
# 按位与运算
masked_img = cv2.bitwise_and(original, original, mask=mask)
直方图分析对比
| 特征指标 | 原始直方图 | 均衡化后直方图 |
|---|---|---|
| 分布形态 | 瘦高型集中分布 | 矮胖型均匀分布 |
| 动态范围 | 集中在狭窄亮度区间 | 覆盖0-255全范围 |
| 对比度表现 | 细节模糊 | 细节清晰可见 |
关键技术参数
-
数据类型规范
掩码矩阵必须声明为dtype=np.uint8,否则会导致按位运算失败 -
直方图预处理
需要先计算归一化概率分布:
p(rk)=nkMN p(r_k) = \frac{n_k}{MN} p(rk)=MNnk
其中nkn_knk为灰度级kkk的像素数,MNMNMN为图像总像素数 -
灰度值映射
最终新灰度值需执行四舍五入:
sk=round(255⋅∑j=0kp(rj)) s_k = round(255 \cdot \sum_{j=0}^k p(r_j)) sk=round(255⋅j=0∑kp(rj))
效果验证方法
- 并排显示原始图像与处理结果
- 叠加绘制均衡化前后直方图曲线
- 使用
cv2.imshow()对比局部细节差异 - 通过PSNR/SSIM指标量化改善程度
课时22:均衡化效果_笔记
直方图均衡化
均衡化示例

基本操作:使用 cv2.equalizeHist(img) 函数实现直方图均衡化,只需传入灰度图像即可完成变换。
效果对比:均衡化后直方图分布从“尖峰状”变为“扁平状”,原图中较少的灰度值(如小值区域)在均衡化后明显增多。
代码演示:
import cv2
import numpy as np
img = cv2.imread('input.jpg', 0)
equ = cv2.equalizeHist(img)
cv2.imshow('Original vs Equalized', np.hstack((img, equ)))
cv2.waitKey(0)
均衡化对比

视觉差异:原始图像(左)色彩较淡,细节模糊;均衡化图像(右)对比度增强,整体更明亮。
细节变化:通过 np.hstack() 将原图与均衡化结果水平拼接展示,可直观比较两者的亮度分布差异。
典型应用:适用于需要增强图像整体对比度的场景,如医学影像、低光照图像处理。
均衡化示例验证

效果验证:在人物面部图像中,均衡化使皮肤区域亮度提升,但可能丢失阴影细节。
局限性:全局均衡化会导致高光区域过曝(如面部反光)或阴影细节消失(如五官轮廓)。
数据说明:示例使用灰度值矩阵演示均衡化计算过程,包含像素概率和累积概率的完整转换公式:
[
s_k = T(r_k) = (L-1) \sum_{j=0}^{k} \frac{n_j}{N}
]
自适应直方图均衡化

改进原理:将图像划分为局部区域单独均衡化,避免全局处理导致的细节丢失。
关键参数:
clipLimit=2.0:对比度限制阈值tileGridSize=(8,8):分块尺寸
实现方法:
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
cl1 = clahe.apply(img)
自适应直方图均衡化示例

效果对比:
- A(原始):细节完整但对比度低
- B(全局均衡):丢失纹理细节
- C(自适应):保留细节同时提升对比度
边界处理:OpenCV 通过双线性插值消除分块边界痕迹。
适用场景:适用于需要保留局部特征的图像,如人脸识别中的微表情或医学影像的病灶区域。
直方图图像处理总结

核心功能:
- 分析图像灰度分布(
cv2.calcHist) - 可视化像素强度分布(
plt.hist)
核心方法:
- 全局均衡化:简单快速,适合整体低对比度图像
- 自适应均衡化:保留局部特征,计算复杂度较高
典型应用链:
- 读取灰度图像(
cv2.imread('img.jpg', 0)) - 计算原始直方图
- 选择均衡化方法
- 可视化对比结果
知识小结表格展示
| 类别 | 核心内容 | 操作演示 | 技术对比 |
|---|---|---|---|
| 直方图均衡化 | 改善图像像素分布不均匀问题 | 使用OpenCV的equalizeHist()函数处理猫图像 |
全局均衡化 vs 自适应均衡化 |
| 自适应均衡化 | 分块处理保留局部细节 | CLAHE算法实现8×8网格处理 | 消除全局均衡化的细节丢失问题 |
| 效果对比 | 亮度/细节/噪声的平衡 | 展示原始图/全局均衡/自适应均衡三组对比 | 自适应方法在纹理保留上表现更优 |
| 技术原理 | 像素值重新分配 | 演示直方图分布变化(尖峰变平缓) | 全局处理导致局部特征模糊 |
| 应用场景 | 医学影像/卫星图增强 | 展示人脸处理前后的细节变化 | 高噪环境需谨慎使用 |
| 函数/方法 | 参数说明 | 优势 | 局限性 |
|---|---|---|---|
equalizeHist() |
单通道灰度图输入 | 简单高效 | 丢失局部细节 |
CLAHE() |
clipLimit/tileGridSize |
保留纹理特征 | 网格边界需插值处理 |
| 直方图分析 | bins/range统计 |
直观显示分布 | 需配合可视化解读 |
补充说明
- 技术对比:全局均衡化可能导致局部特征模糊,而自适应方法(如CLAHE)通过分块处理能更好地保留细节。
- 参数说明:
clipLimit控制对比度限制,tileGridSize决定分块大小(如8×8)。 - 可视化建议:使用Matplotlib绘制均衡化前后的直方图分布对比,增强理解。
课时23:频率变换结果_笔记
傅里叶变换:

时域与频域对比
时域分析
以时间为参照的分析方式,如早上7点吃早饭、8点挤地铁等随时间变化的事件。
频域分析
从更高视角观察事件的重复规律,如"每天吃早饭"、"工作日挤地铁"等周期性行为。
核心观点
在时域中一切是动态进行的,而在频域中所有现象都是静止的周期性规律。
频域概念
频域定义
- 上帝视角比喻:频域就像上帝视角,不关心具体时间点发生什么,只关注事件的重复规律。
- 例子:篮球比赛得分分析,时域描述为"第1分钟得3分,第2分钟得2分",频域则描述为"每隔1分钟得3分和2分交替"。
- 数学本质:任何周期现象都可以分解为不同频率的正弦波组合。
频域图像
- 叠加原理:
- 1个正弦波
- 2个正弦波叠加
- 4个正弦波叠加(更接近矩形波)
- 10个正弦波叠加(几乎形成标准矩形波)
- 关键结论:要精确表示90度矩形波需要无穷多个正弦波叠加。
周期函数的频域表示
- 观察方法:将时域波形从侧面观察即得到频域表示。
- 振幅轴:表示正弦波的强度。
- 频率轴:表示正弦波的周期倒数。
- 波形特征:
- 低频部分:变化缓慢,振幅较大(如基础波形)。
- 高频部分:变化剧烈,振幅较小(如细节部分)。
傅里叶变换的作用

频率分量分析
- 高频:对应图像中变化剧烈的部分(如边缘、细节)。
- 低频:对应图像中变化缓慢的部分(如平滑区域、大面积色块)。
滤波应用
- 低通滤波:保留低频使图像模糊(去噪、平滑)。
- 高通滤波:保留高频增强图像细节(边缘检测)。
OpenCV实现
- 核心函数:
cv2.dft()(正变换)和cv2.idft()(逆变换)。 - 输入要求:需先转换为
np.float32格式。 - 结果处理:频率0点在左上角,需用
shift变换移到中心。 - 输出特性:返回双通道(实部+虚部),需转换到
(0,255)范围显示。
傅里叶变换基础概念
核心内容为时域(时间维度)到频域(频率维度)的转换。例如:
- 时域:日常生活作息(如7点起床、12点午餐)关注时间顺序的动态过程。
- 频域:篮球比赛得分统计(如场均得分频率)关注事件发生的周期性规律。
关键对比在于时域强调时间顺序,频域聚焦频率和振幅,忽略时间细节。
频域的核心特征
通过“上帝视角”比喻,频域仅提取周期性规律(如“每天吃早饭”的频率),不记录具体发生时间。
- 核心特征:频域图形横轴为频率,纵轴为振幅,直接反映信号的组成成分。
- 易混淆点:频域分析会丢失时域的时间顺序信息,但保留事件重复出现的规律。
正弦波叠加原理
任何周期函数可通过不同频率的正弦波叠加近似。例如矩形波的拟合:
- 低频正弦波对应信号的整体轮廓(振幅大)。
- 高频正弦波补充细节(如快速变化的边缘,振幅小)。
难度在于理解高频分量对信号快速变化的贡献,需结合逐步叠加的动画演示。
时域与频域的直观映射
通过多正弦波叠加图展示转换关系:
- 时域波形:复杂信号由多个正弦波合成,时间轴显示瞬时状态。
- 频域分布:横轴为频率,纵轴为振幅,清晰显示各频率分量的强度。
关键对比:频域图中高频分量位于右侧,低频位于左侧。
应用场景示例
图像处理中,傅里叶变换用于:
- 噪声分离:高频成分常对应图像噪声(如锐利边缘),可通过滤波去除。
- 数据压缩:保留主要低频成分,减少高频细节以压缩文件大小。
需注意频域分析适用于周期性或平稳信号,非周期信号需短时傅里叶变换(STFT)等扩展方法。
表格形式建议:
| 知识点 | 核心内容 | 易混淆点/关键对比 | 难度系数 |
|---|---|---|---|
| 傅里叶变换基础 | 时域到频域的抽象转换(如作息时间→频率统计) | 时域动态 vs 频域静态 | ⭐⭐ |
| 频域特征 | 仅关注周期性规律(“每天吃早饭”的频率) | 忽略时间顺序,保留频率振幅 | ⭐⭐ |
| 正弦波叠加 | 矩形波由多正弦波拟合,高频分量对应快速变化 | 高频振幅小但贡献细节 | ⭐⭐⭐ |
| 时域-频域映射 | 频域图横轴频率、纵轴振幅,反映信号组成 | 高频在右,低频在左 | ⭐⭐ |
| 图像处理应用 | 频域分离噪声(高频)或压缩数据(保留低频) | 需区分周期/非周期信号的处理方法 | ⭐⭐⭐ |
课时24:低频和高频的使用_笔记
傅里叶变换的作用
高频
定义:图像中变化剧烈的灰度分量
特征:边界区域(如船与水的交界处)灰度值变化迅速,对应频域图像的外围区域
示例:茫茫大海中突然出现一艘船,水和船之间形成明显差异
低频
定义:变化缓慢的灰度分量
特征:非边界区域(如茫茫大海)灰度值变化平缓,对应频域图像的中心区域
比喻:像老年人慢慢悠悠的动作
滤波
低通滤波器
作用:保留低频信息,去除高频
效果:图像变模糊(边界信息减弱)
原理:抑制频域图像外围区域
高通滤波器
作用:保留高频信息,去除低频
效果:图像细节增强(边界锐化)
原理:抑制频域图像中心区域
OpenCV中的函数

核心函数cv2.dft():执行傅里叶变换cv2.idft():执行逆傅里叶变换
注意事项
输入图像需转换为np.float32格式
频率为0的部分初始在左上角,需通过shift变换到中心
返回结果为双通道(实部+虚部),需转换为图像格式(0-255)显示
处理流程
图像转float32
执行cv2.dft()
使用np.fft.fftshift()中心化
计算幅度谱:20*np.log(cv2.magnitude())
可视化显示
傅里叶变换实现示例

关键步骤
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('lena.jpg', 0)
img_float32 = np.float32(img)
dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
magnitude_spectrum = 20*np.log(cv2.magnitude(dft_shift[:,:,0], dft_shift[:,:,1]))
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()
频域分析结果解读

特征解读
中心区域:低频分量(亮度高)
外围区域:高频分量(亮度低)
离中心越远频率越高
物理意义
低频:图像整体轮廓
高频:图像细节和边缘
傅里叶变换在图像处理中的应用
低通滤波器实现
核心步骤
读取图像并转换为浮点格式:img_float32 = np.float32(img)
傅里叶变换:dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT)
频谱中心化:dft_shift = np.fft.fftshift(dft)
创建掩膜:中心区域设为1,其余为0
逆变换还原图像
掩膜原理
通过mask[crow-30:crow+30, ccol-30:ccol+30] = 1保留中心低频区域
实际效果会使图像变得模糊,保留整体轮廓但弱化细节
技术要点
中心位置计算:crow, ccol = int(rows/2), int(cols/2)
掩膜尺寸:60×60像素区域(±30)
逆变换前需执行np.fft.ifftshift还原频谱位置
高通滤波器实现
实现差异
掩膜初始值设为1:mask = np.ones((rows, cols, 2), np.uint8)
中心区域清零:mask[crow-30:crow+30, ccol-30:ccol+30] = 0
效果特征
突出图像边缘和细节
主体内部区域变为空白
适合边缘检测等应用场景
频域处理优势
分离低频/高频成分更直观
计算效率高于空间域卷积
可通过简单矩阵运算实现复杂滤波效果
傅里叶变换核心概念
基本流程
关键特性
低频分量对应图像整体结构
高频分量对应图像细节和噪声
频谱中心化后低频集中在图像中心
显示处理
使用cv2.magnitude计算幅值
对数变换增强可视化:20*np.log(cv2.magnitude(...))
双通道结果需转换为单通道显示
以下是整理后的知识小结表格,涵盖傅里叶变换及频域处理的核心内容:
| 分类 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
|---|---|---|---|
| 傅里叶变换基本概念 | 将图像从空间域转换到频域进行分析处理 | 频域中低频/高频的分布规律(低频集中在中心) | ⭐⭐⭐ |
| 低通滤波器原理 | 保留低频信息(图像平滑区域),过滤高频信息(边缘细节) | 应用效果:图像模糊化(如示例中帽子/脸部细节丢失) | ⭐⭐ |
| 高通滤波器原理 | 保留高频信息(边缘轮廓),过滤低频信息(平滑区域) | 应用效果:边界锐化(如示例仅保留人像轮廓) | ⭐⭐ |
| OpenCV实现关键步骤 | 1. 强制转换为float32格式2. fftshift中心化处理3. 双通道结果转图像格式 |
易忽略点:逆变换前需ifftshift还原频域分布 |
⭐⭐⭐⭐ |
| 频域处理优势 | 在频域中分离低频/高频比空间域操作更高效 | 典型应用场景:噪声消除(低频)/ 边缘增强(高频) | ⭐⭐⭐ |
关键说明
- 低频/高频分布:频域图像中心区域通常代表低频分量(图像整体结构),外围为高频分量(细节和噪声)。
- 滤波器效果对比:低通滤波器平滑图像但损失细节,高通滤波器突出边缘但削弱整体结构。
- OpenCV注意事项:频域操作需严格遵循
float32格式转换和频谱中心化步骤,否则可能导致结果异常。
课时25:信用卡数字的识别_笔记
实际项目实战:银行卡卡号识别系统
流程解析

项目目标
输入银行卡图像后,识别并输出卡号数字序列及其对应位置,类似车牌识别系统。
输出要求
需要分组输出数字序列(如4000 1234 5678 9010),每组数字需用矩形框标注在原图上。
技术基础
需掌握OpenCV基本操作、形态学处理技术、模板匹配方法、图像预处理技术。
模板准备
必须使用与目标字体风格一致的模板(如银行卡专用字体),包含完整数字集0-9,每个数字需单独提取保存。
轮廓检测
对模板图像进行轮廓检测,优先选择外轮廓(数字的外边界),获取每个数字的外接矩形。
匹配原理
将待识别区域与所有模板数字进行相似度计算,采用平方差等匹配方法,相似度最高的模板数字即为识别结果。

预处理流程
图像处理
图像灰度化、二值化处理、轮廓检测、外接矩形获取。
轮廓筛选
根据长宽比过滤非数字轮廓(如文字logo),银行卡数字具有特定长宽比例特征,保留符合数字特征的轮廓。
尺寸归一化
将检测区域resize到与模板相同尺寸,保证匹配时的尺度一致性。
基本思想小结

核心方法
基于模板匹配的数字识别,结合轮廓检测的精确定位。
关键技术点
模板的准确性和适配性,轮廓检测的准确性,预处理的质量控制。
实现步骤
准备专用数字模板库,输入图像预处理,粗定位数字区域,精确定位单个数字,模板匹配识别,结果输出与可视化。
知识小结表格
| 知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
|---|---|---|---|
| 模板匹配原理 | 通过对比目标区域与预存模板的相似度(如平方差计算)识别数字 | 需区分模板匹配与特征匹配的适用场景 | ⭐⭐ |
| 轮廓检测应用 | 提取数字外轮廓后生成外接矩形,用于标准化匹配区域 | 注意过滤非数字轮廓(如文字/logo)的长宽比筛选 | ⭐⭐ |
| 预处理流程 | 灰度转换→二值化→形态学操作(开运算/闭运算)优化轮廓质量 | 形态学操作顺序对结果影响显著 | ⭐⭐⭐ |
| 银行卡数字识别步骤 | 1. 模板数字分离 2. 输入图像区域检测 3. 轮廓匹配与Resize 4. 分组输出 | 四分组逻辑需与卡号标准格式对齐 | ⭐⭐ |
| 项目实战难点 | 字体特异性(如银行卡专用字体需定制模板) | 模板字体一致性决定匹配准确率 | ⭐⭐⭐⭐ |
课时26:环境配置和预处理_笔记
模板匹配
参数设置
核心参数需要指定输入图像(I)和模板图像(t)两个参数,通过命令行执行时使用-i和-t参数传递参数作用。
-i:指定输入图像的路径,如信用卡图像
-t:指定模板图像的路径,包含待匹配的数字模板
代码实现
通过首数字识别信用卡类型,定义信用卡类型映射字典。
环境配置
开发工具选择
工具要求需要支持debug功能的IDE,不限定具体工具。
推荐工具包括Eclipse(支持多语言:Python/Java/C)、PyCharm、Jupyter Notebook。
选择建议根据项目需求,代码量大时推荐使用支持debug的IDE。
配置运行环境
参数配置方法
:右键点击.py文件选择"Run As",选择"Run Configurations",在"Program arguments"中输入参数:
-i images/credit_card_03.png
-t images/ocr_a_reference.png
点击Apply保存配置。
文件路径说明
:输入图像存放在images目录下,如credit_card_03.png;模板图像为ocr_a_reference.png,包含0-9的数字模板。路径规范使用相对路径,确保文件结构一致。
运行验证依赖库主要需要OpenCV库。配置完成后直接运行,验证是否能正常输出结果。调试建议遇到问题时可通过debug模式逐行检查代码执行。
图像处理流程
灰度处理和二值处理
灰度转换将彩色模板图像转换为灰度图,使用函数,参数为二值化处理。
对灰度图进行阈值处理,使用函数,参数为(反二值化),阈值设为10,最大值255。
处理原因轮廓检测需要输入二值图像,且原图背景为白色(255),数字为黑色(0),反二值化后数字变为白色(255)。
检测轮廓
轮廓检测使用函数,参数为只检测外轮廓,仅保留轮廓终点坐标。
外接矩形检测到轮廓后计算每个数字的外接矩形,用于后续模板匹配。
轮廓排序使用方法按从左到右顺序排列数字轮廓。
模板匹配
匹配过程对信用卡图像中的每个数字区域与模板进行匹配。
结果验证示例中正确识别出信用卡类型为MasterCard,卡号为5412751234567890。
应用场景该方法同样适用于车牌检测等类似场景。
步骤详解
读入模板图像
图像特性模板图像边界为白色(像素值255),数字为黑色。
读取方法使用读取参数指定的模板路径。
调试建议建议在首次实现时使用debug模式逐步查看图像处理结果。
转为灰度图
转换原因减少计算量,简化后续处理步骤。
转换方法使用进行BGR到灰度的转换。
注意事项灰度图仍保留原始图像的明暗关系,但仅含单通道。
二值化处理
阈值选择阈值设为10,低于阈值设为0(黑),高于阈值设为255(白)。
反二值化使用使数字区域变为白色(255),便于轮廓检测。
处理必要性轮廓检测函数要求输入必须是二值图像。
OCR模板匹配流程
| 知识点核心内容 | 考试重点/易混淆点 | 难度系数 |
|---|---|---|
| 通过Python实现信用卡数字识别 | 参数设置(-I输入图像,-t模板路径) |
⭐⭐⭐ |
| 图像预处理、轮廓检测、模板匹配 | 灰度与二值化转换的阈值选择 |
IDE选择与调试技巧
| 知识点核心内容 | 考试重点/易混淆点 | 难度系数 |
|---|---|---|
| 推荐使用Eclipse进行多语言开发 | 环境配置灵活性(Notebook/PyCharm等均可替代) | ⭐⭐ |
| Debug逐行分析的重要性 | 断点设置与变量监控的实践技巧 |
图像预处理技术
| 知识点核心内容 | 考试重点/易混淆点 | 难度系数 |
|---|---|---|
| 灰度转换→二值化→形态学操作 | 形态学操作顺序对结果的影响(如顶帽优先于Sobel) | ⭐⭐⭐⭐ |
| 轮廓检测与外接矩形计算 | 膨胀次数对轮廓闭合性的影响 |
模板匹配实战演示
| 知识点核心内容 | 考试重点/易混淆点 | 难度系数 |
|---|---|---|
| 分步切割信用卡数字区域 | 轮廓分组逻辑(按坐标或面积筛选) | ⭐⭐⭐⭐ |
| 与模板对比输出结果(如5412→7512) | 匹配精度优化(归一化相关系数 vs 平方差) |
项目学习方法论
| 知识点核心内容 | 考试重点/易混淆点 | 难度系数 |
|---|---|---|
| 通过Debug拆解复杂代码 | 断点设置技巧(条件断点、异常断点) | ⭐⭐ |
| 避免整体阅读导致的混乱 | 变量监控与表达式评估的实时应用 |
课时27:模板处理方法_笔记
信用卡数字识别
轮廓检测

- 关键参数:使用
cv2.findContours()时,第一个参数需要传入图像的.copy()副本,因为原始图像后续还需要使用。 - 轮廓模式:参数
cv2.RETR_EXTERNAL表示只检测外轮廓,内轮廓对数字识别任务无用。 - 轮廓近似方法:使用
cv2.CHAIN_APPROX_SIMPLE来保留轮廓的关键坐标点。 - 绘制技巧:
cv2.drawContours()中参数-1表示绘制所有检测到的轮廓,颜色(0,0,255)为红色线条,线宽3像素。 - 验证方法:通过
np.array(refCnts).shape检查轮廓数量是否正确(信用卡数字应有10个轮廓)。
轮廓排序

- 排序必要性:检测到的轮廓顺序不一定对应数字
0-9的自然顺序,需要手动排序。 - 核心步骤:计算每个轮廓的外接矩形
cv2.boundingRect(),提取矩形左上角坐标(x,y),根据x坐标进行从左到右排序。 - 实现细节:外接矩形返回值为
(x,y,w,h)四元组,使用myutils.sort_contours()自定义排序函数,排序后轮廓索引即对应数字值(0轮廓对应数字0)。 - 验证方法:排序后应确保轮廓顺序与数字显示顺序完全一致。
模板匹配

- 模板提取:对每个排序后的轮廓获取外接矩形,使用矩形坐标从原图截取
ROI区域:ref[y:y+h, x:x+w]。 - 统一
resize到标准尺寸(57,88)。 - 字典存储:创建
digits字典存储数字模板,键为数字(0-9),值为对应的ROI图像。 - 注意事项:必须使用
.copy()保留原始图像,每个数字模板尺寸需保持一致,建议在每步处理后显示中间结果验证正确性。
完整流程
- 轮廓检测
- 轮廓排序
- 提取模板
- 构建数字模板字典
知识小结表格
| 知识点 | 核心内容 | 易混淆点/注意事项 | 操作演示 |
|---|---|---|---|
| 轮廓检测 | 使用外轮廓检测功能,忽略内轮廓,用于计算外接矩形 | 必须使用.copy()避免引用问题;参数设置:CV_RETR_EXTERNAL(仅检测外轮廓) |
调用cv2.findContours()并指定mode=cv2.RETR_EXTERNAL |
| 轮廓排序 | 通过外接矩形左上角坐标(x,y)对轮廓进行排序 | 轮廓顺序不固定,需手动排序 | 使用cv2.boundingRect()获取坐标,按x轴排序 |
| 模板提取 | 从排序后的轮廓中截取ROI区域作为数字模板 | 需注意ROI边界(x:x+w, y:y+h);对抠图结果进行resize统一尺寸 |
切片操作:image[y:y+h, x:x+w]后调用cv2.resize() |
| 字典映射 | 建立数字(0-9)与对应模板图像的映射关系 | 枚举索引i需与排序后的轮廓严格对应 |
遍历轮廓并存储到字典:{i: ROI_image} |
| 调试技巧 | 实时显示轮廓/打印数量验证步骤正确性 | 负值参数(如-1)表示绘制全部轮廓 |
使用cv2.imshow()和print(len(contours))辅助调试 |
课时28:输入数据和识别结果_笔记
轮廓检测
绘制轮廓

处理顺序在图像经过阈值化、形态学等预处理后才计算轮廓,绘制时选择在原始彩色图像上显示。
使用cv2.drawContours()函数,参数设置为-1表示绘制所有轮廓,(0,0,255)表示用红色绘制。
处理后会出现多个不规则轮廓,需要通过特征过滤保留有效轮廓(如信用卡数字区域)。
边界矩形
通过cv2.boundingRect()获取轮廓的外接矩形参数(x,y,w,h)。
计算宽高比,信用卡数字的典型范围为特定比例。
同时满足宽度像素和高度像素的条件,符合条件的轮廓坐标存入locs列表,每个元素为(x,y,w,h)四元组。
轮廓排序
检测到的4个数字轮廓需要按实际排列顺序(从左到右)进行排序。
通常根据轮廓的x坐标值进行升序排列。
排序后轮廓编号1-4对应实际卡号的数字顺序。
经过长宽比和尺寸双重筛选后,仅保留4个有效数字区域轮廓。
阈值参数需要根据具体任务调整,不同信用卡的字体尺寸可能有差异。
模板匹配
遍历轮廓数字

在大轮廓中分割出四个小轮廓,对每个小轮廓与0-9的模板数字进行匹配。
使用红色标记处理区域以提高可视性。
轮廓扩展技巧
在原始轮廓基础上向外扩展5个像素,确保完整包含数字特征。
避免因轮廓检测不精确导致的特征丢失。
预处理步骤
二值化处理后进行轮廓检测,仅检测外轮廓。
轮廓排序从左到右排列检测到的数字轮廓。
模板匹配关键参数
将检测区域resize到与模板相同的57×88大小。
采用相关系数匹配法,通过获取最大匹配得分。
流程展示

模板准备阶段预处理参考图像,提取并排序0-9的数字模板存储为字典结构。
输入处理阶段读取信用卡图像,灰度化+二值化处理,形态学操作平滑图像。
数字识别阶段定位数字组区域,分割单个数字与模板匹配,计算得分取最高分作为识别结果。
结果可视化
用红色矩形框标记识别区域,在框上方显示识别结果。
最终输出信用卡类型和完整卡号。
实际应用要点
相同模板可适用于不同信用卡,通过修改输入图像路径测试不同卡片。
扩展应用
适用场景包括车牌识别等类似场景,关键差异在于需要调整轮廓筛选条件。
改进方向可结合OCR技术提升准确率。
以下为整理后的表格形式呈现:
知识点核心内容与考试重点
| 知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
|---|---|---|---|
| 形态学操作 | 使用不同大小的核进行图像预处理(9×3和5×5核) | 核大小的选择依据实际任务需求 | ⭐⭐ |
| 顶帽操作 | 突出图像中更明亮的区域(如字体区域) | 与底帽操作的区别及应用场景 | ⭐⭐ |
| 索贝尔算子 | 仅使用x方向梯度比xy联合效果更好 | 梯度方向选择的实验验证 | ⭐⭐⭐⭐ |
| 开闭运算 | 先膨胀后腐蚀(闭运算)使离散区域连成整体 | 开闭运算的先后顺序差异 | ⭐⭐ |
| 双峰阈值法 | 使用OTSU自动确定最佳阈值 | 与传统固定阈值法的对比 | ⭐⭐⭐⭐ |
| 轮廓检测 | 通过长宽比过滤无效轮廓(信用卡数字区域) | 轮廓层级关系的理解 | ⭐⭐⭐⭐ |
| 模板匹配 | 使用57×88标准化尺寸进行数字识别 | 匹配方法选择(相关系数法) | ⭐⭐⭐⭐ |
| ROI扩展技巧 | 轮廓坐标±5像素的边界扩展方法 | 扩展量与识别精度的平衡 | ⭐⭐ |
| 多级轮廓处理 | 先定位数字组再识别单个数字的两阶段策略 | 轮廓排序算法的实现 | ⭐⭐⭐⭐ |
| 实际应用验证 | 通过更换信用卡图片测试算法泛化能力 | 模板通用性与场景适应性 | ⭐⭐ |
表格说明
- 形态学操作:核尺寸需根据目标特征调整,如细长文本适合9×3核。
- 顶帽操作:常用于增强亮背景中的暗细节,易与底帽(突出暗背景中的亮区域)混淆。
- 索贝尔算子:x方向梯度对垂直边缘敏感,实际效果需通过实验验证。
- 双峰阈值法:OTSU适用于直方图呈双峰分布的图像,否则效果可能不佳。
- 轮廓层级:需理解
cv2.RETR_TREE等参数对嵌套轮廓的影响。
课时29:文档轮廓提取_笔记
文档轮廓提取
边缘检测

预处理步骤
转为灰度图:将图像从BGR转为灰度。
高斯滤波:去除噪声,常用(5,5)核大小。
Canny边缘检测:设置双阈值75和200进行边缘提取。
检测原理
通过红色框标识目标检测区域,过滤背景干扰。
关键参数:边缘检测结果直接影响后续轮廓提取的准确性。
获取轮廓

轮廓近似方法
使用多边形近似,精度控制为轮廓周长的2%作为近似阈值。
四点判断:当近似结果为4个点时即为目标矩形轮廓。
轮廓筛选
按面积或周长排序取前5个轮廓,通过绿色线条绘制最终轮廓。
特殊处理:对于多文档场景,可保留多个四点轮廓。
透视变换

变换原理
包含平移、旋转、翻转等操作的复合变换。
计算变换矩阵并执行实际变换。
坐标处理
使用函数规范坐标顺序(左上、右上、右下、左下)。
变换后保持内容不变,仅改变呈现角度。
尺寸计算
通过欧式距离公式计算变换后图像的宽度和高度。
取最大宽度和高度作为输出尺寸。
文字识别
OCR工具
使用Tesseract OCR进行字符识别,支持中英文、数字混合识别。
需单独安装配置OCR引擎。
后处理
对变换结果进行二次图像增强,包括二值化、去噪等操作以提高识别率。
识别结果可结构化输出为文本数据。
应用案例
购物小票扫描处理
难点:任意角度拍摄导致的形变,复杂背景下的轮廓提取,小票内容的精确识别。
解决方案:通过边缘检测+轮廓近似定位小票区域,透视变换校正图像角度,OCR识别商品信息和价格。
阅读理解文档扫描
特殊处理:多段落文本的分区域处理,保持原始文档的版式结构,针对印刷体优化识别参数。
文档轮廓提取
调试技巧:使用比例参数保持原图坐标关系,分步骤可视化中间结果,关键点坐标的规范化处理。
参数调整:边缘检测阈值的动态调整,轮廓近似精度的优化,输出尺寸的自适应计算。
文档扫描流程技术要点
| 核心内容 | 关键步骤/技术要点 | 应用场景 |
|---|---|---|
| 边缘检测 | 高斯滤波去噪 → 灰度转换 → Canny边缘检测 | 图像预处理阶段 |
| 轮廓检测 | 按面积/周长排序轮廓 → 多边形近似(4点判定矩形) | 目标区域提取 |
| 透视变换 | 计算原图与目标图4点坐标映射 → cv2.warpPerspective |
图像几何校正 |
| OCR集成 | 使用开源工具包(如Tesseract)处理透视变换结果 | 文字信息提取 |
参数调整优化方法
| 优化方向 | 具体实现 | 作用 |
|---|---|---|
| Resize比例计算 | 保持原始图像与坐标的同步缩放比例 | 避免坐标映射失真 |
| 轮廓近似精度控制 | 设置多边形近似阈值(通常为轮廓周长的2%) | 提高矩形区域判定精度 |
代码实现示例(边缘检测与透视变换)
import cv2
import numpy as np
# 边缘检测示例
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(blurred, 75, 200)
# 透视变换示例
def four_point_transform(image, pts):
rect = order_points(pts)
(tl, tr, br, bl) = rect
width = max(np.linalg.norm(tr - tl), np.linalg.norm(br - bl))
height = max(np.linalg.norm(bl - tl), np.linalg.norm(br - tr))
dst = np.array([[0, 0], [width, 0], [width, height], [0, height]], dtype="float32")
M = cv2.getPerspectiveTransform(rect, dst)
warped = cv2.warpPerspective(image, M, (int(width), int(height)))
return warped
技术要点说明
- Canny边缘检测:通过双阈值(低阈值75,高阈值200)控制边缘连接性,优先保留强边缘。
- 多边形近似:使用
cv2.approxPolyDP时,需根据轮廓周长动态调整epsilon值(如周长的2%)。 - 坐标映射同步:在图像缩放(resize)时,需同步调整轮廓坐标,防止透视变换错位。
课时30:原始与变换公式+透视变换结果_笔记
透视变换所需参数

两组坐标点:原始坐标通过轮廓检测获得的四个点(a,b,c,d),目标坐标是期望输出的标准矩形四点(e,f,g,h)。
比例因子用于将检测到的坐标点还原到原始图像尺寸,因为原始图像可能经过resize操作。
矩阵计算需要8个方程求解3×3变换矩阵,每组坐标点提供2个方程,因此需要4组坐标点。
透视变换过程

坐标排序按顺序排列为左上(tl)、右上(tr)、右下(br)、左下(bl)。
宽度计算取底边宽度(widthA)和顶边宽度(widthB)的最大值,高度计算取左侧高度(heightA)和右侧高度(heightB)的最大值。
目标坐标生成标准矩形坐标为:[0,0], [maxWidth-1,0], [maxWidth-1,maxHeight-1], [0,maxHeight-1],减1操作是为了避免数组越界。
坐标转换原理先将二维坐标转换为齐次坐标(增加z=1维度),通过3×3变换矩阵进行三维空间变换,最后将结果投影回二维平面。
矩阵求解条件要求四个原始点不能共线,必须构成四边形,OpenCV的getPerspectiveTransform函数自动完成矩阵计算。
代码执行结果

变换矩阵示例包含具体的数值示例。
后处理步骤包括灰度化将结果转换为单通道灰度图像,二值化使用阈值处理保留有效信息。
结果显示对比展示原始图像和变换后结果。
### 应用场景
文档扫描将倾斜文档转换为标准矩形。
OCR预处理为后续文字识别提供规整的输入图像。
图像校正修复透视变形问题。
以下是整理后的知识点表格:
透视变换技术要点总结
| 类别 | 核心内容 | 关键步骤/注意事项 |
|---|---|---|
| 原理 | 将歪斜图像转换为规整文档的坐标映射技术 | 需两组坐标:原始图像轮廓点 + 目标矩形点 |
计算宽度和高度时取最大值:max(w1,w2) 和 max(h1,h2) |
||
| 坐标点要求 | 必须提供4组非共线点(通常为矩形轮廓) | 点顺序需明确:左上→右上→右下→左下 |
| 每组点包含(x,y)坐标,共需8个方程解算变换矩阵 | ||
| 变换矩阵计算 | 通过cv2.getPerspectiveTransform()求解3×3齐次矩阵 |
输入原始坐标与目标坐标(如[(0,0), (w,0), (w,h), (0,h)]) |
| 矩阵含8个未知数,需归一化处理 | ||
| 图像后处理 | 灰度化+二值化以突出有效信息 | 透视变换后需调整显示范围(w-1, h-1防止越界) |
| 适用场景 | 文档扫描、OCR预处理 | 结果为字符识别提供规整输入 |
| OCR关联应用 | 需提取文本区域(如小票商品名、价格) | 技术栈组合:OpenCV透视变换 + OCR引擎(如Tesseract) |
更多推荐
所有评论(0)