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

学习日记 8.1

前言

前一篇文章讲了图片读取与显示,今天继续看图像运算、阈值处理和噪声去除。主要涉及:

  • 图像运算:图像的加法运算与加权融合
  • 阈值处理:二值化、截断等阈值操作,以及图像边框的填充
  • 噪声去除:椒盐噪声的生成与多种滤波器的去噪效果对比

一、图像运算

1.1 使用 NumPy 的加法(+ 运算符)

直接用+运算符做图像加法,但 NumPy 的加法是取模运算

import cv2 a1 = cv2.imread("3.png") b1 = cv2.imread("4.jpg") a1 = cv2.resize(a1, (500, 400)) b1 = cv2.resize(b1, (500, 400)) NumPy 加法:像素值相加后对 256 取模 c1 = a1 + 10 # 每个像素值加 10 c2 = a1[50:450, 50:400] + b1[50:450, 50:400] # ROI 区域相加

当像素值超过 255 时,NumPy 会将其对 256 取模。例如250 + 10 = 260,取模后变成260 % 256 = 4,这会导致原本应该更亮的区域反而变暗,出现“溢出回绕”的现象。

1.2 使用 OpenCV 的 cv2.add() 函数

OpenCV 提供了专门的加法函数cv2.add(),它的处理方式是饱和运算——超过 255 的值会被截断为 255:

a2 = cv2.imread("3.png") b2 = cv2.imread("4.jpg") b2 = cv2.resize(b2, (400, 400)) a2 = cv2.resize(a2, (400, 400)) OpenCV 加法:超过 255 的像素值会被截断为 255(饱和运算) c3 = cv2.add(a2, b2)
运算方式函数溢出处理
NumPy 加法img1 + img2取模运算(% 256)
OpenCV 加法cv2.add(img1, img2)饱和运算(截断到 255)

小结:在处理图像加法时,推荐使用cv2.add(),因为它避免了取模操作带来的“反色”异常,视觉效果更加自然。

1.3 图像加权融合 —— cv2.addWeighted()

有时候我们希望将两张图像按照一定比例混合,而不是简单地相加。这时候就可以使用cv2.addWeighted()

# 参数:img1, 权重1, img2, 权重2, 亮度偏移量 c4 = cv2.addWeighted(a2, 0.7, b2, 0.3, 100)

公式为:dst = α · img1 + β · img2 + γ,其中 α 和 β 是两幅图像的权重,γ 是亮度调节参数。在上面的代码中,a2占 70% 的权重,b2占 30%,最后再加上 100 的亮度偏移。这个函数在图像叠加、水印添加、视频特效等场景中很常用。

二、图像边框与阈值处理

2.1 为图像添加边框 —— cv2.copyMakeBorder()

为图像添加边框可以用cv2.copyMakeBorder(),支持多种填充方式:

import cv2 ys = cv2.imread("4.jpg") top, bottom, left, right = 50, 50, 50, 50 1. 常量边框:用固定颜色填充 constant = cv2.copyMakeBorder(ys, top, bottom, left, right, borderType=cv2.BORDER_CONSTANT, value=[229, 25, 80]) 2. 镜像边框:以边缘为轴进行镜像 reflect = cv2.copyMakeBorder(ys, top, bottom, left, right, borderType=cv2.BORDER_REFLECT) 3. 镜像边框(不含边界):与 REFLECT 类似但不包含边界像素 reflect101 = cv2.copyMakeBorder(ys, top, bottom, left, right, borderType=cv2.BORDER_REFLECT101) 4. 复制边框:复制边缘像素 replicate = cv2.copyMakeBorder(ys, top, bottom, left, right, borderType=cv2.BORDER_REPLICATE) 5. 环绕边框:用对面边界的像素填充 warp = cv2.copyMakeBorder(ys, top, bottom, left, right, borderType=cv2.BORDER_WRAP)

五种边框类型的效果对比:

边框类型OpenCV 常量说明
常量边框BORDER_CONSTANT用指定颜色值填充边框区域
镜像边框BORDER_REFLECT以边缘像素为镜像轴,向外镜像扩展,如 fedcba|abcdefgh|hgfedcb
反射101BORDER_REFLECT101以边缘像素为对称中心,如 gfedcb|abcdefgh|gfedcba
复制边框BORDER_REPLICATE直接复制最边缘的像素值,如 aaaaaa|abcdefgh|hhhhhhh
环绕边框BORDER_WRAP用对面边界的像素来填充,如 cdefgh|abcdefgh|abcdefg

默认推荐:BORDER_REFLECT101 是 OpenCV 中许多函数(如滤波)的默认边框处理方式,它在大多数场景下表现最佳。

2.2 阈值处理 —— cv2.threshold()

阈值处理是图像分割中最基础的方法之一:设定一个阈值,将像素值与阈值比较,根据比较结果对像素分类。OpenCV 提供了五种阈值处理类型:

image = cv2.imread("4.jpg", 0) # 以灰度模式读取 参数:源图像, 阈值, 最大值, 阈值类型 ret, binary = cv2.threshold(image, 175, 255, cv2.THRESH_BINARY) # 二值化 ret1, binaryinv = cv2.threshold(image, 175, 255, cv2.THRESH_BINARY_INV) # 反二值化 ret2, trunc = cv2.threshold(image, 175, 255, cv2.THRESH_TRUNC) # 截断 ret3, tozero = cv2.threshold(image, 175, 255, cv2.THRESH_TOZERO) # 阈值归零 ret4, tozeroinv = cv2.threshold(image, 175, 255, cv2.THRESH_TOZERO_INV) # 反阈值归零
阈值类型处理规则效果描述
THRESH_BINARYdst = maxVal 若 src > thresh,否则 0超过阈值为白色,否则为黑色
THRESH_BINARY_INVdst = 0 若 src > thresh,否则 maxVal二值化的反转版本
THRESH_TRUNCdst = thresh 若 src > thresh,否则 src超过阈值的像素被截断为阈值
THRESH_TOZEROdst = src 若 src > thresh,否则 0低于阈值的像素归零
THRESH_TOZERO_INVdst = 0 若 src > thresh,否则 src高于阈值的像素归零

返回值ret是实际使用的阈值(在使用 Otsu 等自适应方法时可能与传入值不同),binary等是处理后的图像。

应用场景:阈值处理常用于文档扫描二值化、物体轮廓提取、前景/背景分离等任务。

三、图像噪声与滤波

3.1 椒盐噪声的生成

椒盐噪声(Salt-and-Pepper Noise)是图像中常见的噪声类型,表现为随机出现的黑白像素点(像撒了盐和胡椒一样)。可以手动模拟这种噪声:

import numpy as np def add_peppersalt_noise(image, n=10000): """向图像添加椒盐噪声 Args: image: 输入图像 n: 噪声点数量 Returns: 添加了噪声的图像 """ result = image.copy() h, w = image.shape[:2] # 获取图像的高和宽 for i in range(n): x = np.random.randint(0, h) # 随机行坐标 y = np.random.randint(0, w) # 随机列坐标 if np.random.randint(0, 2) == 0: result[x][y] = 0 # 黑点(胡椒噪声) else: result[x][y] = 255 # 白点(盐噪声) return result

这段代码会在图像的随机位置生成黑白噪声点,模拟真实场景中的椒盐噪声。

3.2 均值滤波 —— cv2.blur() 与 cv2.boxFilter()

均值滤波是最简单的线性滤波方法,它用像素邻域的平均值来替代中心像素的值:

# 均值滤波:5x5 的卷积核 blur_1 = cv2.blur(noise, (5, 5)) 方框滤波:当 normalize=True 时与均值滤波等效 boxFilter_1 = cv2.boxFilter(noise, -1, (3, 3), normalize=True) 方框滤波:normalize=False 时,求和但不平均(容易溢出) boxFilter_2 = cv2.boxFilter(noise, -1, (3, 3), normalize=False)
参数说明
-1输出图像的深度,-1表示与输入图像一致
(3, 3)卷积核大小
normalize=True是否对结果进行归一化处理

注意:normalize=False时,方框滤波不再除以核面积,像素值容易超过 255,导致画面一片白。

3.3 高斯滤波 —— cv2.GaussianBlur()

高斯滤波使用高斯函数作为权重分配,离中心越近的像素权重越大,去噪的同时能更好地保留边缘信息:

# 高斯滤波:核大小 (3,3),标准差为 1 Gaussian_Noise = cv2.GaussianBlur(noise, (3, 3), 1)

参数说明:(3, 3)是高斯核的大小(必须是奇数),1是 X 方向的标准差(如果设为 0,则根据核大小自动计算)。

3.4 中值滤波 —— cv2.medianBlur()

中值滤波是非线性滤波,它用邻域像素的中值替代中心像素,对椒盐噪声的去除效果尤其出色:

# 中值滤波:核大小为 3 medianB = cv2.medianBlur(noise, 3)

3.5 滤波效果对比

结论:对于椒盐噪声,中值滤波是首选方案。它能在有效去除椒盐噪声的同时最大限度地保留图像的边缘细节。


四、综合实战

4.1 实战一:摄像头实时画面与背景图融合

这是一个综合运用图像运算的实战案例,实现摄像头实时画面与背景图片的融合效果:

import cv2 cap = cv2.VideoCapture(0) background = cv2.imread('4.jpg') background = cv2.resize(background, (640, 480)) background_gray = cv2.cvtColor(background, cv2.COLOR_BGR2GRAY) if not cap.isOpened(): print("无法打开摄像头") exit() while True: ret, frame = cap.read() if not ret: break frame = cv2.resize(frame, (640, 480)) frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 彩色融合(各占 50% 透明度) c1 = cv2.addWeighted(frame, 0.5, background, 0.5, 100) 灰度融合(各占 50% 透明度) c2 = cv2.addWeighted(frame_gray, 0.5, background_gray, 0.5, 100) cv2.imshow('Color Fusion', c1) cv2.imshow('Gray Fusion', c2) 按下 ESC 键退出 if cv2.waitKey(60) == 27: break cap.release() cv2.destroyAllWindows()

4.2 实战二:视频椒盐噪声处理

对视频文件逐帧添加椒盐噪声,并使用中值滤波进行去噪:

import cv2 import numpy as np def add_peppersalt_noise(image, n=8000): result = image.copy() h, w = image.shape[:2] for i in range(n): x = np.random.randint(0, h) y = np.random.randint(0, w) if np.random.randint(0, 2) == 0: result[x][y] = 0 else: result[x][y] = 255 return result cap = cv2.VideoCapture("test.avi") if not cap.isOpened(): print("无法打开视频文件") exit() while True: ret, frame = cap.read() if not ret: break # 添加椒盐噪声 noise = add_peppersalt_noise(frame) 中值滤波去噪 medianB = cv2.medianBlur(noise, 3) 同时显示三个窗口 cv2.imshow('Original', frame) # 原视频 cv2.imshow('Noise', noise) # 含噪声视频 cv2.imshow('Denoised', medianB) # 去噪后视频 if cv2.waitKey(60) == 27: break cap.release() cv2.destroyAllWindows()

五、总结

今天的学习内容涵盖了 OpenCV 图像处理的三个核心模块:

模块核心函数要点
图像运算cv2.add(),cv2.addWeighted()区分 NumPy 取模加法与 OpenCV 饱和加法;掌握加权融合
阈值处理cv2.threshold(),cv2.copyMakeBorder()五种阈值类型 + 五种边框填充方式
滤波去噪cv2.blur(),cv2.boxFilter(),cv2.GaussianBlur(),cv2.medianBlur()椒盐噪声首选中值滤波

这些知识都是后续学习更高级图像处理操作(如边缘检测、形态学操作、轮廓提取等)的基础,建议动手运行每一段代码,观察不同参数带来的效果变化。

http://www.cnnetsun.cn/news/3808373.html

相关文章:

  • Java实现书籍标题生成器的核心技术解析
  • Excel跨工作表求和全攻略:从SUM三维引用到动态汇总实战
  • Xbatis:持久层代码直降 2/3,多版本更新有亮点、多种查询写法超方便!
  • OPC UA技术专家如何通过知识管理实现品牌化增长
  • 量化交易的市场博弈与散户防御策略
  • SAP利润中心会计(CO-PCA)核心架构与实战应用解析
  • 文本功能分析:从语义理解到沟通骨架解构
  • GIS本科生如何构建核心竞争力与提升就业价值
  • iPhone黑解证书备份:原理、风险与越狱环境下的实操指南
  • IL-21信号通路与抗体融合蛋白的免疫治疗应用
  • SpringBoot社区疫情防控系统开发实践
  • 6款AI写作辅助软件盘点
  • 华硕笔记本性能解放:3个颠覆性改变让G-Helper成为Armoury Crate的终极替代方案
  • 物联网智能家居系统:从架构设计到自动化场景的实战解析
  • 训练数据偏见导致审核失准?深度拆解237万条标注样本中的隐性偏差链,附可复用校准Checklist
  • Flutter表单引擎lyform鸿蒙HarmonyOS迁移实战
  • SSH作业
  • UEditor实现Word图片批量上传技术方案
  • 从PHP到K8s全栈覆盖,HostMod 给AI建站补上了企业级托管能力
  • C++ OJ题解优化与竞赛编程技巧
  • RISC-V中auipc指令原理与NEMU模拟器实现详解
  • 【YOLO26创新改进】PR 2026顶刊 | 特征融合改进篇 | 使用LCAFusion轻量交叉注意力融合模块,适合可见光—红外目标检测,无人机遥感目标检测、低照度与恶劣天气检测、旋转目标检测任务
  • 2026年本科生必备的10大AI工具指南
  • 竞价优化公司说的“行业大盘数据”是从哪来的?
  • 上下文工程
  • DAMA框架:企业数据资产化与治理实践指南
  • 硬核抗老:防晒如何阻挡光老化痕迹
  • TypeScript 入门指南
  • 华为S5700交换机系统文件丢失故障诊断与完整恢复指南
  • 英雄联盟豹女陷阱流玩法解析:符文出装与实战博弈