Python Opencv实战之图像阈值和模糊处理,万字实战,收藏起来吧~

是Dream呀 发表于 2022/02/25 22:53:56 2022/02/25
【摘要】 Python Opencv实战之图像阈值和模糊处理,万字实战,收藏起来吧~

在这里插入图片描述

📢📢📢📣📣📣
🌻🌻🌻Hello,大家好我叫是Dream呀,一个有趣的Python博主,小白一枚,多多关照😜😜😜
🏅🏅🏅CSDN Python领域新星创作者,大二在读,欢迎大家找我合作学习
💕入门须知:这片乐园从不缺乏天才,努力才是你的最终入场券!🚀🚀🚀
💓最后,愿我们都能在看不到的地方闪闪发光,一起加油进步🍺🍺🍺
🍉🍉🍉“一万次悲伤,依然会有Dream,我一直在最温暖的地方等你”,唱的就是我!哈哈哈~🌈🌈🌈
🌟🌟🌟✨✨✨

一、图像阈值

cv2.threshold()函数的作用是将一幅灰度图二值化,基本用法如下:

ret,mask = cv2.threshold(src, dst, thresh, maxval, type) 
plt.imshow(mask,cmap='gray')

输出参数:

(ret,mask)

ret: 输入的thresh值。
mask: 处理后的图像。

输出参数:

(src, dst, thresh, maxval, type)

src: 输入源图像(灰度图)。
thresh:阈值,用于对像素值进行分类。
maxval:最大值(分配给超过阈值的像素值的最大值)。
type:阈值类型,OpenCV提供了由函数的第四个参数给出的不同类型的阈值。

threshold函数:

  • cv2.THRESH_BINARY 超过阈值部分取maxval(最大值),否则取0
  • cv2.THRESH_BINARY_INV THRESH_BINARY的反转
  • cv2.THRESH_TRUNC 大于阈值部分设为阈值,否则不变
  • cv2.THRESH_TOZERO 大于阈值部分不改变,否则设为0
  • cv2.THRESH_TOZERO_INV THRESH_TOZERO的反转

实例演示:

# -*-coding:utf-8 -*-
# @Author:到点了,心疼徐哥哥
# 奥利给干!!!
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img=cv.imread('haojin.jpg',0)  # 灰色
ret,a1=cv.threshold(img,127,255,cv.THRESH_BINARY)
ret,a2=cv.threshold(img,127,255,cv.THRESH_BINARY_INV)
ret,a3=cv.threshold(img,127,255,cv.THRESH_TRUNC)
ret,a4=cv.threshold(img,127,255,cv.THRESH_TOZERO)
ret,a5=cv.threshold(img,127,255,cv.THRESH_TOZERO_INV)
titles=['Original','BINARY','THRESH_BINARY_INV','THRESH_TRUNC','THRESH_TOZERO','THRESH_BINARY_INV']
imgs=[img,a1,a2,a3,a4,a5]
for i in range(6):
    plt.subplot(2,3,i+1),plt.imshow(imgs[i],'gray')#显示灰度图时 plt.imshow(dataArray) 要指定一个参数 cmap='gray'
    plt.title(titles[i])
    # plt.xticks([]),plt.yticks([])
    plt.axis('off')
plt.show()

在这里插入图片描述
不变成灰色图:
在这里插入图片描述

在这里插入图片描述

二、图像平滑与滤波

运用它,首先就要了解它

什么是平滑滤波?

平滑滤波是低频增强的空间域滤波技术。它的目的有两类:一类是模糊另一类是消除噪音。空间域的平滑滤波一般采用简单平均法进行,就是求邻近像元点的平均亮度值。邻域的大小与平滑的效果直接相关,邻域越大平滑的效果越好,但邻域过大,平滑会使边缘信息损失的越大,从而使输出的图像变得模糊,因此需合理选择邻域的大小。

1. 2D卷积(图像过滤)

与一维信号一样,还可以使用各种低通滤波器(LPF)高通滤波器(HPF)等对图像进行滤波。LPF有助于消除噪声,使图像模糊等。HPF滤波器有助于在图像中找到边缘。

OpenCV提供了一个函数cv.filter2D来将内核与图像进行卷积。例如,我们将尝试对图像进行平均滤波。5x5平均滤波器内核如下所示:
在这里插入图片描述
操作如下: 保持这个内核在一个像素上,将所有低于这个内核的25个像素相加,取其平均值,然后用新的平均值替换中心像素。它将对图像中的所有像素继续此操作。试试这个代码,并检查结果:

# -*-coding:utf-8 -*-
# @Author:到点了,心疼徐哥哥
# 奥利给干!!!
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img=cv.imread('logo.png')
kernel=np.ones((5,5),np.float32)/25
# print(kernel)
dst=cv.filter2D(img,-1,kernel)
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.axis('off')
plt.subplot(122),plt.imshow(dst),plt.title('Averaging')
plt.axis('off')
plt.show()

1.1 filter2D()函数:

函数原型:

dst=cv.filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]])

参数描述:
在这里插入图片描述

1.2 np.ones()函数

参数介绍:

  • shape , 单个整数,或整数序列,例如(2,3,4)或2;
  • dtype ,数据类型,例如 np.int8, 或 np.float64;
  • order , { ‘F’, C’} ,存储多为数组 是以行优先 ’C‘ ,还是列优先 ’F‘ ; 默认’C‘ ,行优先;
print('kernel')

在这里插入图片描述

1.3结果检测:

在这里插入图片描述

2. 图像模糊(图像平滑)

通过将图像与低通滤波器内核进行卷积来实现图像模糊。这对于消除噪音很有用。它实际上从图像中消除了高频部分(例如噪声,边缘)。因此,在此操作中边缘有些模糊。(有一些模糊技术也可以不模糊边缘)。OpenCV主要提供四种类型的模糊技术。

2.1.平均

这是通过将图像与归一化框滤镜进行卷积来完成的。它仅获取内核区域下所有像素的平均值,并替换中心元素。这是通过功能cv.blur() 或 cv.boxFilter() 完成的。检查文档以获取有关内核的更多详细信息。我们应该指定内核的宽度和高度。3x3归一化框式过滤器如下所示:
在这里插入图片描述
均值滤波也称为线性滤波,其采用的主要方法为邻域平均法。线性滤波的基本原理是用均值代替原图像中的各个像素值,即对待处理的当前像素点(x,y),选择一个模板,该模板由其近邻的若干像素组成,求模板中所有像素的均值,再把该均值赋予当前像素点(x,y),作为处理后图像在该点上的灰度g(x,y),即g(x,y)=1/m ∑f(x,y) m为该模板中包含当前像素在内的像素总个数。
函数实现:

cv2.blur(img,ksize) , ksize为卷积核的大小,也可以表示进行均值滤波的方框大小

(a,b)表示的卷积核[大小] a代表横向上的模糊,b表示纵向上的模糊

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img=cv.imread('logo.png')
blur = cv.blur(img,(5,5))
# blur = cv.GaussianBlur(img,(5,5),0)
print(blur)
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.axis('off')
plt.subplot(122),plt.imshow(blur),plt.title('Blurred')
plt.axis('off')
plt.show()

知识补充:卷积核

1、卷积核就相当于数字图像处理中的滤波算子。

2.大部分卷积核是奇数的,为啥?
奇数相对于偶数,有中心点,对边沿、对线条更加敏感,可以更有效的提取边沿信息。
偶数也可以使用,但是效率比奇数低。在数以万计或亿计的计算过程中,每个卷积核差一点,累计的效率就会差很多。

3.卷积核的格式
例如:一个(3,3,64,32)的卷积核意思是:卷积核高度、卷积核宽度、输入通道数、输出通道数
具体意思是:32个64通道数的3*3的卷积核和输入进行卷积 输出32个卷积结果。

结果展示:
在这里插入图片描述

2.2 高斯模糊

在这种情况下,代替盒式滤波器,使用了高斯核。这是通过功能cv.GaussianBlur() 完成的。我们应指定内核的宽度和高度,该宽度和高度应为正数和奇数。我们还应指定X和Y方向的标准偏差,分别为sigmaX和sigmaY。如果仅指定sigmaX,则将sigmaY与sigmaX相同。如果两个都为零,则根据内核大小进行计算。高斯模糊对于从图像中去除高斯噪声非常有效。
如果需要,可以使用函数cv.getGaussianKernel() 创建高斯内核。

高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。

函数原型:cv2.GuassianBlur(img, ksize,sigmaX,sigmaY)

参数说明:

  1. img 输入图像
  2. ksize 卷积核大小(必须为正奇数,也可以为0)
  3. 3.sigmaX、sigmaY(x和y方向上的高斯核标准差)
blur = cv.GaussianBlur(img,(5,5),0)

代码实现:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img=cv.imread('logo.png')
# blur = cv.blur(img,(5,5))
blur = cv.GaussianBlur(img,(5,5),0)
print(blur)
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.axis('off')
plt.subplot(122),plt.imshow(blur),plt.title('Blurred')
plt.axis('off')
plt.show()

结果展示:
在这里插入图片描述

2.3 中位模糊

在这里,函数cv.medianBlur() 提取内核区域下所有像素的中值并将中心元素替换为该中值。这对于消除图像中的椒盐噪声非常有效。有趣的是,在上述过滤器中,中心元素是新计算的值,该值可以是图像中的像素值或新值。但是在中值模糊中,中心元素总是被图像中的某些像素值代替。有效降低噪音。其内核大小应为正奇数整数。

中值滤波法是一种非线性平滑技术,它将每一像素点的灰度值设置为该点某邻域窗口内的所有像素点灰度值的中值。

函数实现:cv2.medianBlur(img, k) ,k为方框的尺寸

第二个参数是孔径的尺寸,一个大于1的奇数。
比如这里是5,中值滤波器就会使用5×5的范围来计算。
即对像素的中心值及其5×5邻域组成了一个数值集,对其进行处理计算,当前像素被其中值替换掉。

中值滤波最适合去除椒盐噪声

添加噪声:
在此演示中,我向原始图像添加了50%的噪声并应用了中值模糊。检查结果:

from matplotlib import pyplot as plt
from skimage import io,util

origin = io.imread("logo.png")
img= util.random_noise(origin, mode='gaussian', var=0.5)
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.axis('off')
plt.savefig('50%mohu.jpg', dpi=600, bbox_inches='tight')
plt.show()


在这里插入图片描述
代码展示:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img=cv.imread('mohu.png')
# blur = cv.blur(img,(5,5))
# blur = cv.GaussianBlur(img,(5,5),0)
median = cv.medianBlur(img,3)
# print(blur)
# print(median)
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.axis('off')
plt.subplot(122),plt.imshow(median),plt.title('Blurred')
plt.axis('off')
plt.show()

结果展示:
在这里插入图片描述

2.4 双边滤波

cv.bilateralFilter()去除噪声的同时保持边缘清晰锐利非常有效。但是,与其他过滤器相比,该操作速度较慢。我们已经看到,高斯滤波器采用像素周围的邻域并找到其高斯加权平均值。高斯滤波器仅是空间的函数,也就是说,滤波时会考虑附近的像素。它不考虑像素是否具有几乎相同的强度。它不考虑像素是否是边缘像素。因此它也模糊了边缘,这是我们不想做的。

双边滤波器在空间中也采用高斯滤波器但是又有一个高斯滤波器,它是像素差的函数空间的高斯函数确保仅考虑附近像素的模糊,而强度差的高斯函数确保仅考虑强度与中心像素相似的那些像素的模糊。由于边缘的像素强度变化较大,因此可以保留边缘。
以下示例显示了使用双边过滤器:

blur = cv.bilateralFilter(img,9,75,75)

代码展示:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img=cv.imread('mohu.png')
blur = cv.bilateralFilter(img,9,75,75)
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.axis('off')
plt.subplot(122),plt.imshow(blur),plt.title('Blurred')
plt.axis('off')
plt.show()

结果展示:
在这里插入图片描述

🌲🌲🌲 好啦,这就是今天要分享给大家的全部内容了
❤️❤️❤️如果你喜欢的话,就不要吝惜你的一键三连了~
在这里插入图片描述
在这里插入图片描述

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。