python opencv图像处理(七)

简介: python opencv图像处理(七)

图像平滑(滤波)处理


这里先介绍一下图像的一些问题


每一幅图像都包含某种程度的噪声,噪声可以理解为由一种或者多种原因造成的灰度值的随机变化,如由光子通量的随机性造成的噪声等等。


而图像平滑技术或者是图像滤波技术就是用来处理图像上的噪声,其中,能够具备边缘保持作用的图像平滑处理,成为了大家关注的重点。


本文会介绍 OpenCV 中提供的图像平滑的 4 个算法:


  • 均值滤波
  • 方框滤波
  • 高斯滤波
  • 中值滤波

先给之前的小姐姐做一个噪声处理吧

代码如下:


import cv2 as cv
import numpy as np
# 读取图片
img = cv.imread("data.jpg", cv.IMREAD_UNCHANGED)
rows, cols, chn = img.shape
# 加噪声
for i in range(5000):
    x = np.random.randint(0, rows)
    y = np.random.randint(0, cols)
    img[x, y, :] = 255
cv.imshow("noise", img)
# 图像保存
cv.imwrite("maliao_noise.jpg", img)
# 等待显示
cv.waitKey()
cv.destroyAllWindows()


在这里随机将一些像素值改问255,白色



2D图像卷积


在介绍滤波之前先简单介绍下 2D 图像卷积,图像卷积其实就是图像过滤。


图像过滤的时候可以使用各种低通滤波器( LPF ),高通滤波器( HPF )等对图像进行过滤。


低通滤波器( LPF )有助于消除噪声,但是会使图像模糊。


高通滤波器( HPF )有助于在图像中找到边缘。


OpenCV 为我们提供了一个函数 filter2D() 来将内核与图像进行卷积。


我们尝试对图像进行平均滤波, 5 x 5 平均滤波器内核如下:


20210706133125184.png

具体操作如下:


我们保持这个内核在一个像素上,将所有低于这个内核的 25 个像素相加,取其平均值,然后用新的平均值替换中心像素。它将对图像中的所有像素继续此操作,完整的示例代码如下:


import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
# 读取图片
img = cv.imread("data.jpg", cv.IMREAD_UNCHANGED)
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
kernel = np.ones((5,5),np.float32)/25
dst = cv.filter2D(rgb_img, -1, kernel)
titles = ['Source Image', 'filter2D Image']
images = [rgb_img, dst]
for i in range(2):
    plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()

20210707154748537.png

均值滤波


均值滤波是指任意一点的像素值,都是周围 N * M 个像素值的均值。


其实均值滤波和上面的那个图像卷积的示例,做了同样的事情,我只是用 filter2D() 这个方法手动完成了均值滤波,实际上 OpenCV 为我们提供了专门的均值滤波的方法,前面图像卷积没有看明白的同学,可以再一遍均值滤波,我尽量把这个事情整的明白的。


还是来画个图吧:

20210706133312454.png


中间那个红色的方框里面的值,是周围 25 个格子区域中的像素的和去除以 25 ,这个公式是下面这样的:


2021070613333452.png

上面这个 5 * 5 的矩阵称为核,针对原始图像内的像素点,采用核进行处理,得到结果图像。


这个核我们可以自定义大小,比如 5 * 5 ,3 * 3 , 10 * 10 等等,具体定义多大完全看疗效。


OpenCV 为我提供了 blur() 方法用作实现均值滤波,原函数如下:


def blur(src, ksize, dst=None, anchor=None, borderType=None)


kSize:内核参数,其实就是图片进行卷积的时候相乘的那个矩阵,具体的卷积是如何算的,网上有很多,我这里就不介绍了,所得到的图像是模糊的,而且图像其实是按照原来的比例缺少了(原图像-内核参数+1)^2个单元格。

anchor: Point 类型,即锚点,有默认值 Point(-1, -1) ,当坐标为负值,就表示取核的中心。

borderType: Int 类型,用于推断图像外部像素的某种边界模式,有默认值 BORDER_DEFAULT 。

接下来是均值滤波的示例代码:


import cv2 as cv
import matplotlib.pyplot as plt
# 读取图片
img = cv.imread("data.jpg", cv.IMREAD_UNCHANGED)
rgb_img = cv.cvtColor(img, cv.COLOR_BGR2RGB)
# 均值滤波
blur_img = cv.blur(rgb_img, (3, 3))
# blur_img = cv.blur(img, (5, 5))
# blur_img = cv.blur(img, (10, 10))
# blur_img = cv.blur(img, (20, 20))
titles = ['Source Image', 'Blur Image']
images = [rgb_img, blur_img]
for i in range(2):
    plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()

20210707154834601.png

这个降噪的效果好像没有前面 2D 卷积的那个降噪效果好,但是图像更为清晰,因为我在这个示例中使用了更小的核 3 3 的核,顺便我也试了下大核,比如代码中注释掉的 10 10 的核或者 20 * 20 的核,实时证明,核越大降噪效果越好,但是相反的是图像会越模糊。


方框滤波


方框滤波和均值滤波核基本一致,其中的区别是需不需要进行归一化处理。

什么是归一化处理等下再说,我们先看方框滤波的原函数:


def boxFilter(src, ddepth, ksize, dst=None, anchor=None, normalize=None, borderType=None)


src: 原始图像。

ddepth: Int 类型,目标图像深度,通常用 -1 表示与原始图像一致。 kSize: 内核参数。

dst:输出与 src 大小和类型相同的图像。

anchor: Point 类型,即锚点,有默认值 Point(-1, -1) 。

normalize: Int 类型,表示是否对目标图像进行归一化处理。

当 normalize 为 true 时,需要执行均值化处理。


当 normalize 为 false 时,不进行均值化处理,实际上是求周围各像素的和,很容易发生溢出,溢出时均为白色,对应像素值为 255 。


完整示例代码如下:


import cv2 as cv
import matplotlib.pyplot as plt
# 读取图片
img = cv.imread('data.jpg')
source = cv.cvtColor(img, cv.COLOR_BGR2RGB)
# 方框滤波
result = cv.boxFilter(source, -1, (5, 5), normalize = 1)
# 显示图形
titles = ['Source Image', 'BoxFilter Image']
images = [source, result]
for i in range(2):
    plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()

20210707154935134.png

高斯滤波


为了克服简单局部平均法的弊端(图像模糊),目前已提出许多保持边缘、细节的局部平滑算法。它们的出发点都集中在如何选择邻域的大小、形状和方向、参数加平均及邻域各店的权重系数等。


在高斯滤波的方法中,实际上是把卷积核换成了高斯核,那么什么是高斯核呢?


简单来讲就是方框还是那个方框,原来每个方框里面的权是相等的,大家最后取平均,现在变成了高斯分布的,方框中心的那个权值最大,其余方框根据距离中心元素的距离递减,构成一个高斯小山包,这样取到的值就变成了加权平均。


下图是所示的是 3 3 和 5 5 领域的高斯核。



20210707155146480.png

高斯滤波是在 OpenCV 中是由 GaussianBlur() 方法进行实现的,它的原函数如下:


def GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)


sigmaX: 表示 X 方向方差。


这里需要注意的是 ksize 核大小,在高斯核当中,核 (N, N) 必须是奇数, X 方向方差主要控制权重。


完整的示例代码如下


import cv2 as cv
import matplotlib.pyplot as plt
# 读取图片
img = cv.imread('data.jpg')
source = cv.cvtColor(img, cv.COLOR_BGR2RGB)
# 方框滤波
result = cv.GaussianBlur(source, (3, 3), 0)
# 显示图形
titles = ['Source Image', 'GaussianBlur Image']
images = [source, result]
for i in range(2):
    plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()


20210707155328676.png

中值滤波


在使用邻域平均法去噪的同时也使得边界变得模糊。


而中值滤波是非线性的图像处理方法,在去噪的同时可以兼顾到边界信息的保留。


中值滤波具体的做法是选一个含有奇数点的窗口 W ,将这个窗口在图像上扫描,把窗口中所含的像素点按灰度级的升或降序排列,取位于中间的灰度值来代替该点的灰度值。


下图是一个一维的窗口的滤波过程:


20210707155432449.png

在 OpenCV 中,主要是通过调用 medianBlur() 来实现中值滤波,它的原函数如下:


def medianBlur(src, ksize, dst=None)
• 1


示例代码如下:


import cv2 as cv
import matplotlib.pyplot as plt
# 读取图片
img = cv.imread('data.jpg')
source = cv.cvtColor(img, cv.COLOR_BGR2RGB)
# 方框滤波
result = cv.medianBlur(source, 3)
# 显示图形
titles = ['Source Image', 'medianBlur Image']
images = [source, result]
for i in range(2):
    plt.subplot(1, 2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()

20210707155600881.png

可以明显看到,目前中值滤波是对原图像降噪后还原度最高的,常用的中值滤波的图形除了可以使用方框,还有十字形、圆形和环形,不同形状的窗口产生不同的滤波效果。






相关文章
|
算法 计算机视觉
基于qt的opencv实时图像处理框架FastCvLearn实战
本文介绍了一个基于Qt的OpenCV实时图像处理框架FastCvLearn,通过手撕代码的方式详细讲解了如何实现实时人脸马赛克等功能,并提供了结果展示和基础知识回顾。
527 7
基于qt的opencv实时图像处理框架FastCvLearn实战
|
9月前
|
机器学习/深度学习 存储 数据挖掘
Python图像处理实用指南:PIL库的多样化应用
本文介绍Python中PIL库在图像处理中的多样化应用,涵盖裁剪、调整大小、旋转、模糊、锐化、亮度和对比度调整、翻转、压缩及添加滤镜等操作。通过具体代码示例,展示如何轻松实现这些功能,帮助读者掌握高效图像处理技术,适用于图片美化、数据分析及机器学习等领域。
336 20
|
5月前
|
人工智能 算法 计算机视觉
Python 图像处理技巧
本文介绍了Python图像处理中需要掌握的15个基本技能,涵盖图像读取与保存、颜色空间转换、裁剪与调整大小、滤波与平滑、边缘检测、阈值处理、形态学操作、直方图处理、特征检测与描述、图像配准与特征匹配、轮廓检测与分析、图像分割、模板匹配、透视变换与仿射变换以及傅里叶变换等内容。通过OpenCV、Pillow和Matplotlib等库实现相关功能,为图像处理提供了全面的基础指导。
120 0
|
8月前
|
监控 Java 计算机视觉
Python图像处理中的内存泄漏问题:原因、检测与解决方案
在Python图像处理中,内存泄漏是常见问题,尤其在处理大图像时。本文探讨了内存泄漏的原因(如大图像数据、循环引用、外部库使用等),并介绍了检测工具(如memory_profiler、objgraph、tracemalloc)和解决方法(如显式释放资源、避免循环引用、选择良好内存管理的库)。通过具体代码示例,帮助开发者有效应对内存泄漏挑战。
352 1
|
9月前
|
XML 机器学习/深度学习 人工智能
使用 OpenCV 和 Python 轻松实现人脸检测
本文介绍如何使用OpenCV和Python实现人脸检测。首先,确保安装了OpenCV库并加载预训练的Haar特征模型。接着,通过读取图像或视频帧,将其转换为灰度图并使用`detectMultiScale`方法进行人脸检测。检测到的人脸用矩形框标出并显示。优化方法包括调整参数、多尺度检测及使用更先进模型。人脸检测是计算机视觉的基础技术,具有广泛应用前景。
339 10
|
9月前
|
机器学习/深度学习 算法 数据可视化
Python的计算机视觉与图像处理
本文介绍了Python在计算机视觉和图像处理领域的应用,涵盖核心概念、算法原理、最佳实践及应用场景。重点讲解了OpenCV、NumPy、Pillow和Matplotlib等工具的使用,并通过代码实例展示了图像读写、处理和可视化的方法。实际应用包括自动驾驶、人脸识别、物体检测等。未来趋势涉及深度学习、边缘计算和量子计算,同时也讨论了数据不足、模型解释性和计算资源等挑战。
407 2
|
11月前
|
计算机视觉 开发者 Python
利用Python进行简单的图像处理
【10月更文挑战第36天】本文将引导读者理解如何使用Python编程语言和其强大的库,如PIL和OpenCV,进行图像处理。我们将从基本的图像操作开始,然后逐步深入到更复杂的技术,如滤波器和边缘检测。无论你是编程新手还是有经验的开发者,这篇文章都将为你提供新的视角和技能,让你能够更好地理解和操作图像数据。
|
12月前
|
机器学习/深度学习 算法 计算机视觉
【Python篇】Python + OpenCV 全面实战:解锁图像处理与视觉智能的核心技能
【Python篇】Python + OpenCV 全面实战:解锁图像处理与视觉智能的核心技能
335 7
|
12月前
|
计算机视觉 Python
python利用pyqt5和opencv打开电脑摄像头并进行拍照
本项目使用Python的PyQt5和OpenCV库实现了一个简单的摄像头应用。用户可以通过界面按钮打开或关闭摄像头,并实时预览视频流。点击“拍照”按钮可以捕捉当前画面并保存为图片文件。该应用适用于简单的图像采集和处理任务。
721 0
python利用pyqt5和opencv打开电脑摄像头并进行拍照
|
机器学习/深度学习 计算机视觉 Python
opencv环境搭建-python
本文介绍了如何在Python环境中安装OpenCV库及其相关扩展库,包括numpy和matplotlib,并提供了基础的图像读取和显示代码示例,同时强调了使用Python虚拟环境的重要性和基本操作。

推荐镜像

更多