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

opencv基础学习与实战(2)

一,边界填充

cv2.copyMakeBorder()是OpenCV库中的一个函数,用于给图像添加额外的边界(padding)。
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: 使用最边界的像素值代替,类似于aaaaaaa|abcdefgh|hhhhhhh
cv2.BORDER_WRAP: 上下左右边依次替换,cdefgh|abcdefgh|abcdefg

import cv2
ys = cv2.imread('aigc.png')
ys=cv2.resize(ys,dsize=None,fx=0.5,fy=0.5) # 图片缩放
# ys=cv2.resize(ys,(640,480))
top, bottom, left, right = 50,50,50,50
constant = cv2.copyMakeBorder(ys,top,bottom,left,right,borderType=cv2.BORDER_CONSTANT,value=(229,25,80))
reflect = cv2.copyMakeBorder(ys,top,bottom,left,right,borderType=cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(ys,top,bottom,left,right,borderType=cv2.BORDER_REFLECT101)
replicate = cv2.copyMakeBorder(ys,top,bottom,left,right,borderType=cv2.BORDER_REPLICATE)
wrap = cv2.copyMakeBorder(ys,top,bottom,left,right,borderType=cv2.BORDER_WRAP)
cv2.imshow('yuantu', ys)
cv2.waitKey(0)
cv2.imshow('CONSTANT', constant)
cv2.waitKey(0)
cv2.imshow('REFLECT', reflect)
cv2.waitKey(0)
cv2.imshow('REFLECT_101', reflect101)
cv2.waitKey(0)
cv2.imshow('REPLICATE', replicate)
cv2.waitKey(0)
cv2.imshow('WRAP', wrap)
cv2.waitKey(0)

可以观察到图像边缘变化

二,图像的加法运算

1. +号运算

 对图像a、图像b进行加法求和时,遵循以下规则:
---当某位置像素相加得到的数值小于255时,该位置数值为两图像该位置像素相加之和
---当某位置像素相加得到的数值大于255时,该位置数值将截断结果并将其减去 256 例如:相加后是260,实际是260-256= 4

# a = cv2.imread('aigc.png')
# b = cv2.imread('aigc1.jpg')
# c = a + 10  # 图片...
# cv2.imshow('yuan', a)
# cv2.imshow('a+10', c)
# cv2.waitKey(0)
# c=a+b
# cv2.imshow('a+b', c)
# cv2.waitKey(0)

可以观察图像变化

2.cv2.add()运算

当对图像a、图像b进行加法求和时,遵循以下规则:
--当某位置像素相加得到的数值小于255时,该位置数值为两图像该位置像素相加之和
--当某位置像素相加得到的数值大于255时,该位置数值为255

a = cv2.imread('aigc.png')
b = cv2.imread('aigc1.jpg')
b = cv2.resize(b, (400, 400))
a = cv2.resize(a, (400, 400))
c = cv2.add(a, b)  # 也可以使用使用
cv2.imshow('a add b', c)
cv2.waitKey(0)
cv2.destroyAllWindows()

可以观察图像变化,大部分区域是白色

3.图像加权运算
是在计算两幅图像的像素值之和时,将每幅图像的权重考虑进来,可以用公式表示为dst=src1×α+src2×β+γ


# a = cv2.imread('aigc.png')
# b = cv2.imread('aigc1.jpg')
# b = cv2.resize(b, (400, 400))
# a = cv2.resize(a, (400, 400))
# #
# c = cv2.addWeighted(a, alpha=0.2, beta=0.8, gamma=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_BINARY                       maxval                       0
# cv2.THRESH_BINARY_INV               0                             maxval
# cv2.THRESH_TRUNC                       thresh                      当前灰度值
# cv2.THRESH_TOZERO                    当前灰度值               0
# cv2.THRESH_TOZERO_INV            0                              当前灰度值

import cv2
image = cv2.imread('longpic.png',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)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)

可以从左到右依次观察到图像的变化

四,图像平滑处理

图像平滑(smoothing)也称为“模糊处理”(bluring)
通过消除图像中的噪声或细节来使图像看起来更为模糊,从而实现平滑效果
可以用来压制、弱化或消除图像中的细节、突变和噪声。
下面是常用的一些滤波器
均值滤波(邻域平均滤波)-> blur函数
方框滤波-> boxFilter函数
高斯滤波->GaussianBlur函数
中值滤波->medianBlur函数
dst=cv2.blur(src,ksize,anchor,borderType)
dst是返回值
src是需要处理的图像
kszie是滤波核(卷积核)的大小
anchor是锚点,默认值是(-1,-1)一般无需更改
borderType是边界样式,一般无需更改
一般情况下,使用dst=cv2.blur(src,ksize)即可

先为图像添加噪声

import cv2
import numpy as np
def add_peppersalt_noise(image, n=5000):result = image.copy()h, w = image.shape[:2]  # 获取图片的高和宽for i in range(n):  # 生成n个椒盐噪声x = np.random.randint(1, h)y = np.random.randint(1, w)if np.random.randint(0, 2) == 0:result[x, y] = 0else:result[x, y] = 255return resultimage = cv2.imread('longpic.png')
noise = add_peppersalt_noise(image)
cv2.imshow('yantu', image)
cv2.imshow('noise', noise)
cv2.waitKey(0)

可以观察到原图与添加过噪声的图的变化

1,均值滤波

均值滤波是取像素邻域(如 \(3\times3\) 窗口)内所有像素值的平均值,替换中心像素值,以此平滑图像、削弱噪声,但会让图像变模糊。 用数值示例(\(3\times3\) 邻域)更直观: 原始邻域像素值: | 10 | 20 | 15 |                                | 10 | 20 | 15 |

         | 25 | 30 | 22 |               --->            | 25 | 20 | 22 |   

         | 12 | 18 | 25 |                                 | 12 | 18 | 25 |

均值滤波后中心像素值:(10 + 20 + 15 + 25 + 30 + 22 + 12 + 18 + 25)=20,邻域整体数值更平均,噪声被削弱,同时图像细节也变模糊。

blur_1 = cv2.blur(noise, (3, 3))  # 卷积核为3,3  效果一般,清晰度一般
cv2.imshow('blur_1', blur_1)
cv2.waitKey(0)
blur_2 = cv2.blur(noise, (63, 63))
cv2.imshow('blur_2', blur_2)
cv2.waitKey(0)

从右到左可以观察到图像的变化

2,方框滤波

用一个固定大小的 “方框”(如 3x3、5x5)在图像上滑动,方框内所有像素的平均值(或总和)作为中心像素的新值

  • 若 “归一化”(默认):新值 = 方框内像素总和 / 方框像素数量(即均值滤波);
  • 若 “不归一化”:新值 = 方框内像素总和(可能导致像素值溢出,需谨慎使用)。

图像示例:

假设 3x3 方框覆盖的像素值如下(中心像素为 5):

1  2  3  
4  5  6  
7  8  9  

归一化方框滤波后,中心像素新值 =(1+2+3+4+5+6+7+8+9)/9 = 5。

直观效果:方框内像素 “平均化”,模糊效果均匀,但可能模糊边缘细节。

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, (3, 3), normalize=True)  # 2、方框滤波
cv2.imshow('boxFilter_1', boxFilter_1)
cv2.waitKey(0)
boxFilter_2 = cv2.boxFilter(noise, -1, (3, 3), normalize=False)
cv2.imshow('boxFilter_2', boxFilter_2)
cv2.waitKey(0)

3,高斯滤波

原理:

用 “高斯核”(权重符合高斯分布的方框)滑动,方框内像素的加权平均值作为中心像素的新值

  • 高斯核的权重特点:中心像素权重最大,向四周(距离中心越远)权重逐渐减小(符合 “近大远小” 的高斯分布);
  • 本质是 “加权平均”,比方框滤波更注重保留中心附近的像素信息。

图像示例:

以简化的 3x3 高斯核(权重总和为 16)为例,权重分布如下:

1  2  1  
2  4  2  
1  2  1  

覆盖的像素值仍为:

1  2  3  
4  5  6  
7  8  9  

中心像素新值 =(1×1 + 2×2 + 3×1 + 4×2 + 5×4 + 6×2 + 7×1 + 8×2 + 9×1)/16 = 5。

直观效果:平滑噪声的同时,比方框滤波更能保留图像边缘(因中心权重高),是最常用的平滑方法之一。

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

4.中值滤波

原理:

用固定大小的方框滑动,方框内所有像素值排序后,取 “中值” 作为中心像素的新值(而非平均值)。

  • 核心:对极端值(如椒盐噪声中的亮 / 暗点)不敏感,适合去除脉冲噪声。

图像示例:

3x3 方框内的像素值(含椒盐噪声,255 为亮点,0 为暗点):

1   3   255  
7   5   11  
0   15  17  

排序后:[0, 1, 3, 7, 5, 11, 15, 17, 255] → 中值为 5。
中心像素新值 = 5(极端值 255 和 0 被过滤)。

直观效果:能有效去除椒盐噪声,同时比前两种滤波更能保留边缘的锐利度。

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

medianB = cv2.medianBlur(noise, 3)  # 4、中值滤波
cv2.imshow('medianBlur', medianB)
cv2.waitKey(0)
cv2.destroyAllWindows()

我们观察到,中值滤波的效果最好,因为我们的噪声点不是为1就是为255,在排序过程中很容易把0或255排到两边,过滤掉。

http://www.lryc.cn/news/621270.html

相关文章:

  • 基于 LDA 模型的安徽地震舆情数据分析
  • Docker build创建镜像命令入门教程
  • 地测管理部绩效考核关键指标与地质数据分析
  • 码上爬第九题【协程+webpack】
  • C++基础(①入门教程)
  • K8s学习----Namespace:资源隔离与环境管理的核心机制
  • **标题:发散创新,探索编程中的平衡设计****摘要**:本文将探讨如何在编程中运用平衡设计思想,通过实例分析与
  • 37 C++ STL模板库6-string_view
  • 设计模式笔记_行为型_责任链模式
  • 仓颉编程语言的Any 类型(Any 接口)
  • Video-R1论文解读
  • 使用keil5 自带的仿真观察GPIO口波形
  • lib.dom.d.ts
  • 《量子雷达》第4章 量子雷达的检测与估计 预习2025.8.14
  • Windows bypassUAC 提权技法详解(一)
  • ACCESS多个时间段查询,只取整点,30分数据
  • 【读代码】深度解析 context-engineering-intro:开源上下文工程实践原理与应用
  • 【Functions】enumerate的用法
  • 机器学习-基础入门:从概念到核心方法论
  • Data Augmentation数据增强
  • 从0到1:C++ 语法之 nullptr
  • 机器学习内容总结
  • 机器学习初学
  • 前端vue框架
  • 机器学习知识总结
  • 智能体评测技术与实践:从评估维度到DeepEval实战指南
  • 20250814,通义万相,无限生成权限(慢速)
  • Linux中的日志管理
  • Linux中tty与8250-uart的虐恋(包括双中断发送接收机制)
  • 前端包管理工具