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

计算机视觉第一课opencv(二)保姆级教

目录

简介

一、边界填充

1.函数说明

2.案例分析

二、图像运算

1.+号运算

2.cv2.add()函数

3.图像加权运算

三、阈值处理

四、图像平滑处理

1.椒盐噪声

2.均值滤波(Mean Filtering)

3.方框滤波

4. 高斯滤波(Gaussian Filtering)

5.中值滤波(Median Filtering)

总结:


简介

继上一篇博客:

计算机视觉第一课opencv(一)保姆级教

我们了解了关于opencv的一些基本用途,今天我们继续来探究opencv的其他功能

一、边界填充

1.函数说明

cv2.copyMakeBorder()是OpenCV库中的一个函数,用于给图像添加额外的边界(padding)。
cv2.copyMakeBorder(src: UMat, top: int, bottom: int, left: int, right: int, borderType: int, dst: UMat | None = ..., value: cv2.typing.Scalar = ...)
它有以下几个参数:
  • # src: 要扩充边界的原始图像。
  • # top, bottom, left, right: 相应方向上的边框宽度。
  • # borderType: 定义要添加边框的类型,它可以是以下的一种:
  • # cv2.BORDER_CONSTANT: 添加的边框像素值为常数(需要额外再给定一个参数)。
  • # cv2.BORDER_REFLECT: 添加的边框像素将是边界元素的镜面反射,类似于 gfedcba|abcdefgh|hgfedcba。(交界处也复制了)
  • # cv2.BORDER_REFLECT_101 或 cv2.BORDER_DEFAULT: 和上面类似,但是有一些细微的不同,类似于 gfedcb|abcdefgh|gfedcba。(交接处删除了)
  • # cv2.BORDER_REPLICATE: 使用最边界的像素值代替,类似于 aaaaaa|abcdefgh|hhhhhhh
  • # cv2.BORDER_WRAP: 上下左右边界依次替换, cdefgh|abcdefgh|abcdefg

2.案例分析

导入库

import cv2

读取图像

ys = cv2.imread('dama.jpg')
ys=cv2.resize(ys,dsize=None,fx=0.5,fy=0.5)

读取名为dama.jpg的图像文件,注意图像路径需要正确。调整图像大小

设置边界参数

top, bottom, left, right = 50, 50, 50, 50

定义要在图像的上、下、左、右四个方向各添加 50 像素的边界。

五种边界填充方式

# 显示原始图像,窗口名为'yuantu'
cv2.imshow(winname='yuantu', mat=ys)
cv2.waitKey(0)  # 等待按键,按任意键继续

# 常数填充,value指定填充颜色(BGR 格式,这里是(229,25,80) )
constant = cv2.copyMakeBorder(ys, top, bottom, left, right, borderType=cv2.BORDER_CONSTANT, value=(229, 25, 80))
# 依次显示不同填充方式处理后的图像及对应窗口名
cv2.imshow(winname='CONSTANT', mat=constant)
cv2.waitKey(0)

# 镜面反射填充(BORDER_REFLECT 模式)
reflect = cv2.copyMakeBorder(ys, top, bottom, left, right, borderType=cv2.BORDER_REFLECT)
cv2.imshow(winname='REFLECT', mat=reflect)
cv2.waitKey(0)

# 带细微差别的镜面反射填充(BORDER_REFLECT_101 模式,也可用 BORDER_DEFAULT )
reflect101 = cv2.copyMakeBorder(ys, top, bottom, left, right, borderType=cv2.BORDER_REFLECT101)
cv2.imshow(winname='REFLECT_101', mat=reflect101)
cv2.waitKey(0)

# 边界像素复制填充(BORDER_REPLICATE 模式)
replicate = cv2.copyMakeBorder(ys, top, bottom, left, right, borderType=cv2.BORDER_REPLICATE)
cv2.imshow(winname='REPLICATE', mat=replicate)
cv2.waitKey(0)

这里使用白色背景没啥明显效果,可以换成其他图片

# 边界循环填充(BORDER_WRAP 模式)
wrap = cv2.copyMakeBorder(ys, top, bottom, left, right, borderType=cv2.BORDER_WRAP)
cv2.imshow(winname='WRAP', mat=wrap)
cv2.waitKey(0)

二、图像运算

1.+号运算

  • # 当某位置像素相加得到的数值小于255时,该位置数值为两图该位置像素相加之和
    # 当某位置像素相加得到的数值大于255时,该位置数值将被截断结果并将其减去 256  例如:相加后是260,实际是260 - 256 = 4
a = cv2.imread('ting98.jpg')
b = cv2.imread('zl.png')
c = a + 10  # 图片
cv2.imshow('yuan', a)
cv2.imshow('a+10', c)
cv2.waitKey(0)c = a[50:450, 50:400] + b[50:450, 50:400]
cv2.imshow('a+b', c)
cv2.waitKey(0)
  • a[50:450, 50:400] 表示截取图像 a 中从 (50,50) 到 (450,400) 的区域(ROI,感兴趣区域)
  • 要求 a 和 b 的截取区域尺寸完全相同,否则会报错

2.cv2.add()函数

  • # 当某位置像素相加得到的数值小于255时,该位置数值为两图该位置像素相加之和
    # 当某位置像素相加得到的数值大于255时,该位置数值为255
a = cv2.imread('ting98.jpg')
b = cv2.imread('zl.png')
b = cv2.resize(b, dsize=(400, 400))
a = cv2.resize(a, dsize=(400, 400))
c = cv2.add(a, b)  # 也可以使用使用
cv2.imshow('a add b', c)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 必须保证两个图像尺寸和通道数完全一致(这里通过cv2.resize()统一为 400x400)
  • +号操作的区别:超过 255 的像素会被截断为 255(而非模 256),因此亮部更易呈现白色

3.图像加权运算

  • # 就是在计算两幅图像的像素值之和时,将每幅图像的权重考虑进来。可以用公式表示为dst = src1×α + src2×β + γ
  • α:src1 的权重(0~1 之间)
  • β:src2 的权重(0~1 之间,通常 α+β=1)
  • γ:亮度调节常数(可正可负,用于整体提亮或变暗)
a = cv2.imread('ting98.jpg')
b = cv2.imread('zl.png')
b = cv2.resize(b, dsize=(400, 400))
a = cv2.resize(a, dsize=(400, 400))
#
c = cv2.addWeighted(a, 0.2, b, 0.8, 10)  # 10:图像的亮度值(常数),将添加到加权和上
cv2.imshow('addWeighted', c)
cv2.waitKey(0)
cv2.destroyAllWindows()

三、阈值处理

阈值处理是指删除图像内像素值高于一定值或低于一定值的像素点。使用的方法为:
retval, dst=cv2.threshold(src,thresh,maxval,type)
retval代表返回的阈值
#   dst代表阈值分割结果图像,与原始图像具有相同的大小和类型
#   src代表要进行阈值分割的图像,可以是多通道的,8位或32位浮点型数值
#   thresh代表要设定的阈值
#   maxval代表type参数位THRESH_BINARY或者THRESH_BINARY_INV类型时,需要设定的最大值
#   type代表阈值分割的类型,具体内容如下表所示:
选项像素值 > thresh其他情况
cv2.THRESH_BINARYmaxval0
cv2.THRESH_BINARY_INV0maxval
cv2.THRESH_TRUNCthresh当前灰度值
cv2.THRESH_TOZERO当前灰度值0
cv2.THRESH_TOZERO_INV0当前灰度值
import cv2image = cv2.imread('dama.jpg', 1) #为彩色图像,0为灰度图像
# 图像缩放(宽高都缩放到原来的0.5倍)
image = cv2.resize(image, dsize=None, fy=0.5, fx=0.5)# 不同类型的阈值处理
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)# 显示原图
cv2.imshow('gray', image)
cv2.waitKey(0)# 依次显示各阈值处理结果
cv2.imshow('binary', binary)
cv2.waitKey(0)cv2.imshow('binaryinv', binaryinv)
cv2.waitKey(0)cv2.imshow('trunc', trunc)
cv2.waitKey(0)cv2.imshow('tozero', tozero)
cv2.waitKey(0)cv2.imshow('tozeroinv', tozeroinv)
cv2.waitKey(0)

代码说明:

  • 代码使用cv2.threshold()函数实现了五种不同类型的阈值处理
  • 所有处理使用的阈值 (thresh) 都是 175,最大值 (maxval) 都是 255
  • 通过cv2.imshow()cv2.waitKey(0)实现了图像的逐一显示

四、图像平滑处理

        图像平滑(smoothing)也称为“模糊处理”(blurring)
        图像平滑处理是数字图像处理中一种常用的技术,其核心目的是减少或消除图像中的噪声(如随机干扰、斑点等),同时尽可能保留图像的重要细节信息,使图像变得更加平滑、清晰。在实际应用中,图像采集、传输等过程可能会引入噪声,平滑处理能有效改善图像质量,为后续的图像分析、识别等操作奠定基础。
        下面是常用的一些滤波器
          均值滤波(邻域平均滤波)-> blur函数

          方框滤波-> boxFilter函数

          高斯滤波->GaussianBlur函数

         中值滤波->medianBlur函数

1.椒盐噪声

椒盐噪声是数字图像中常见的一种噪声类型,因其外观类似图像上随机分布的黑白斑点(如同撒了盐粒和胡椒粒)而得名。

特点

  • 噪声形态:表现为图像中随机出现的白色亮点(盐噪声,对应像素值为 255,即最大亮度)和黑色暗点(椒噪声,对应像素值为 0,即最小亮度)。
  • 产生原因:通常由图像传感器故障、传输信道干扰(如数据丢失)、模数转换错误等导致,例如相机拍摄时的突发电子干扰、图像压缩或传输中的比特错误等。
  • 分布特性:噪声点在图像中随机分布,数量可多可少,且每个噪声点通常只影响单个像素(少数情况下可能影响相邻像素)。

对图像的影响

椒盐噪声会破坏图像的局部像素信息,导致图像细节模糊或失真,尤其会干扰边缘检测、特征提取等后续图像处理任务的准确性。例如,在文字识别中,椒盐噪声可能导致字符笔画断裂或出现伪影,影响识别率。

对一个图片添加椒盐噪声

import cv2
import numpy as npdef add_peppersalt_noise(image, n=10000):result = image.copy()  # 复制原图,避免修改原图h, w = image.shape[:2]  # 获取图片的高和宽(忽略通道数)for i in range(n):  # 生成n个椒盐噪声点# 随机生成噪声点的坐标x = np.random.randint(1, h)  # 随机行坐标(1到h-1之间)y = np.random.randint(1, w)  # 随机列坐标(1到w-1之间)# 50%概率生成盐噪声(白点),50%概率生成椒噪声(黑点)if np.random.randint(0, 2) == 0:result[x, y] = 0  # 椒噪声(黑色点,像素值0)else:result[x, y] = 255  # 盐噪声(白色点,像素值255)return result
# #
image = cv2.imread('dama.jpg')
image=cv2.resize(image,dsize=None,fx=0.5,fy=0.5)
cv2.imshow(  'yntu',image)
cv2.waitKey(0)
noise = add_peppersalt_noise(image)
cv2.imshow( 'noise',noise)
cv2.waitKey(0)

        我们可以看见第二张图片出现很多黑白色的点,这就是椒盐噪声。接下来我要介绍四种去除椒盐噪声的方法

2.均值滤波(Mean Filtering)

  • 原理:用图像中某个像素周围(如 3×3、5×5 的邻域)所有像素的平均值来替代该像素的值。
  • 实现方式:通过一个固定大小的滑动窗口(卷积核)在图像上移动,窗口内所有像素值的总和除以窗口像素数量,得到的结果作为窗口中心像素的新值。
  • 特点:能有效抑制高斯噪声等,但会使图像边缘变得模糊,窗口越大,平滑效果越明显,但图像细节丢失也越多。

红色点计算公式:(1*12+1*45+128*1+100*1+66*1+212*1+88*1+15*1+215*1)/9

蓝色点计算公式:对于蓝色点我们只能读取四个数据,一般我们会在外面一圈填充0或者1或者中心点的数值进行计算

 dst=cv2.blur(src,ksize,anchor,borderType)
#  dst是返回值
#  src是需要处理的图像
#  kszje是滤波核(卷积核)的大小
#  anchor是锚点,默认值是(-1,-1)一般无需更改
#  borderType是边界样式,一般无需更改
# 一般情况下,使用dst=cv2.blur(src,ksize)即可
blur_1 = cv2.blur(noise, ksize=(3, 3))  # 卷积核为3,3  效果一般,清晰度一般
cv2.imshow('blur_1', blur_1)
cv2.waitKey(0)blur_2 = cv2.blur(noise, ksize=(63, 63))
cv2.imshow('blur_2', blur_2)
cv2.waitKey(0)

3.方框滤波

是指用当前像素点周围nxn个像素值的和来代替当前像素值

dst=cv2.boxFilter (src, ddepth, ksize, anchor, normalize, borderType)

 ● dst是返回值,表示进行方框滤波后得到的处理结果。
    ● src 是需要处理的图像,即原始图像。
   ● ddepth是处理结果图像的图像深度,一般使用-1表示与原始图像使用相同的图像深度。(可以理解为数据类型)
   ● ksize 是滤波核的大小。滤波核大小是指在滤波处理过程中所选择的邻域图像的高 度和宽度。
   ● anchor 是锚点,(指对应哪个区域)
   ● normalize 表示在滤波时是否进行归一化。
       1.当值为True时,归一化,用邻域像素值的和除以面积。 此时方框滤波与 均值滤波 效果相同。
       2.当值为False时,不归一化,直接使用邻域像素值的和。和>255时使用255

boxFilter_1 = cv2.boxFilter(noise, -1, ksize=(3, 3), normalize=True)  # 2、方框滤波
cv2.imshow('boxFilter_1', boxFilter_1)
cv2.waitKey(0)boxFilter_2 = cv2.boxFilter(noise, -1, ksize=(3, 3), normalize=False)
cv2.imshow('boxFilter_2', boxFilter_2)
cv2.waitKey(0)

4. 高斯滤波(Gaussian Filtering)

  • 原理:基于高斯函数设计卷积核,对像素周围邻域进行加权平均,距离中心像素越近的像素权重越大,反之越小。
  • 实现方式:卷积核的数值服从高斯分布,通过该核与图像进行卷积运算,实现平滑处理。
  • 特点:相比均值滤波,在平滑噪声的同时能更好地保留图像边缘信息,对高斯噪声的抑制效果较好。

cv2.GaussianBlur(src, ksize[, sigmaX[, sigmaY[, dst]]])
参数说明:src:输入图像,通常是一个NumPy数组。ksize:滤波器的大小,它是一个元组,表示在水平和垂直方向上的像素数量。例如,(5, 5)表示一个5x5的滤波器。
sigmaX和sigmaY:分别表示在X轴和Y轴方向上的标准差。这些值与滤波器大小相同。默认情况下,它们都等于0,这意味着没有高斯模糊。dst:输出图像,通常是一个NumPy数组。如果为None,则会创建一个新的数组来存储结果。
GaussianB = cv2.GaussianBlur(noise, ksize=(3,3), sigmaX=1) #标准差为1,标准正太分布。 3、高斯滤波
cv2.imshow('GaussianBlur', GaussianB)
cv2.waitKey(0)

5.中值滤波(Median Filtering)

  • 原理:用像素邻域内所有像素值的中值来替代该像素的值。
  • 实现方式:滑动窗口遍历图像,将窗口内的像素值排序后,取中间值作为中心像素的新值。
  • 特点:对椒盐噪声(图像中出现的随机黑白点)抑制效果显著,且不易使图像边缘模糊,是处理椒盐噪声的首选方法。

这就很科学的把0和255给去掉了,也就是白色与黑色

 cv2.medianBlur(src, ksize[, dst])
参数说明:
src:输入图像。
ksize:滤波器的大小,它是一个整数,表示在水平和垂直方向上的像素数量。例如,5表示一个5x5的滤波器。
dst:输出图像,通常是一个NumPy数组。如果为None,则会创建一个新的数组来存储结果。
medianB = cv2.medianBlur(noise, ksize=3)  # 4、中值滤波
cv2.imshow('medianBlur', medianB)
cv2.waitKey(0)
cv2.destroyAllWindows()

总结:

        不同的平滑处理方法各有侧重,选择时需根据图像噪声类型、对图像细节保留的要求等因素综合考虑。例如,处理椒盐噪声优先用中值滤波,需要保留边缘时可选用双边滤波,而处理高斯噪声时高斯滤波是较好的选择。

http://www.dtcms.com/a/330820.html

相关文章:

  • WPF 实现TreeView选中项双向绑定保姆级教程:TreeViewHelper深度解析
  • MySQL缓存策略
  • 计算机视觉--opencv(代码详细教程)(二)
  • iPhone 17 系列发布会定于 9 月 9 日举行-邀请函或 9 月 2 日发出
  • MCP Server搭建
  • OpenCV中对图像进行平滑处理的4种方式
  • 微美全息(WIMI.US)借区块链与聚类技术,开启物联网去中心化安全架构新纪元
  • 我的第一个开源项目-jenkins集成k8s项目
  • .Net4.0 WPF中实现下拉框搜索效果
  • RabbitMQ高级特性——消息确认、持久性、发送方确认、重试
  • 解锁Prompt秘籍:框架、技巧与指标全解析
  • 基于Django的福建省旅游数据分析与可视化系统【城市可换】
  • 《量子雷达》第4章 量子雷达的检测与估计 预习2025.8.14
  • 【51单片机学习】定时器、串口、LED点阵屏、DS1302实时时钟、蜂鸣器
  • 量子人工智能
  • Python训练营打卡Day32-神经网络的训练
  • Swift 数据类型全景解析(基础到高阶)
  • 按位运算的枚举在 Swift 里如何实现?
  • 《吃透 C++ 类和对象(中):拷贝构造函数与赋值运算符重载深度解析》
  • 【数据分享】2014-2023年长江流域 (0.05度)5.5km分辨率的每小时日光诱导叶绿素荧光SIF数据
  • Pytest自动化测试框架总结
  • iOS性能监控新方法多版本对比与趋势分析实战指南
  • C++进阶:特殊类
  • 手写MyBatis第16弹:泛型魔法应用:MyBatis如何破解List的运行时类型
  • 笔试——Day38
  • 根据图片远程地址复制图片内容,可以在富文本、word等文本里粘贴
  • word——删除最后一页空白页
  • Exif.js获取手机拍摄照片的经纬度
  • 【网络】TCP/UDP总结复盘
  • Unity人形角色IK优化指南