#目的为记录在自己运行时存在的问题及解决方法,本文基于CSDN社区的Eastmount大佬的课程,通过学习,其中也增加了自己的考量和问题的解决。
import cv2
import numpy as np
#读取图片
img = cv2.imread("C:/Users/CLH/Desktop/test1.JPG",cv2.IMREAD_UNCHANGED)
rows, cols, chn = img.shape
#加入噪音
for i in range(50000):
x = np.random.randint(0, rows)
y = np.random.randint(0, cols)
img[x,y,:] = 255
#显示图片
cv2.imshow("clh",img)
#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
在图像简单平滑中,算法利用卷积模板逐一处理图像中每个像素,这一过程可以形象地比作对原始图像的像素一一进行过滤整理,在图像处理中把邻域像素逐一处理的算法过程称为滤波器。平滑线性滤波器的工作原理是利用模板对邻域内像素灰度进行加权平均,也称为均值滤波器。
result = cv2.blur(source, (5, 5))
(1)cv2.cvtColor(p1,p2) 是颜色空间转换函数,p1是需要转换的图片,p2是转换成何种格式。cv2.COLOR_BGR2RGB 将BGR格式转换成RGB格式.
(2)plt.subplots 可以创建一个图和一组子图,但每条subplot命令只会创建一个子图。
plt.subplot(i,j,n)形式,其中ij是行列数,n是第几个图,比如(2,2,1)则是一个有四个图,该图位于第一个。
(3)plt.xticks 和 plt.yticks 分别代表了对横纵坐标轴的参数操作,以下方代码为例,[0,200,400]代表将在x轴上的0,200,400三个位置进行标记,[100,300,500]代表对前述位置实际标识的内容,rotation表示字体角度。plt.xticks( [ ] )表示不显示坐标
plt.xticks([0,200,400],[100,300,500],rotation=45)
(4)plt.title 函数用于设置图像标题
(5)plt.imshow 函数负责对图像进行处理,并显示其格式,plt.show则是将plt.imshow处理后的函数显示出来。
代码如下:
import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取图片
img = cv2.imread("C:/Users/CLH/Desktop/test3.JPG",cv2.IMREAD_UNCHANGED)
source = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 均值滤波
result = cv2.blur(source, (5, 5))
# 显示图形
titles = ['Source Image', 'Blur Image']
images = [source, result]
for i in range(2):
plt.subplot(1, 2, i + 1)
plt.imshow(images[i])
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
3. 方框滤波
(1)方框滤波和均值滤波核基本一致,区别是需不需要归一化处理,其函数如下:
result = cv2.boxFilter (原始图像, 目标图像深度, 核大小, normalize属性)。其中,目标图像深度是int类型,通常用“-1”表示与原始图像一致;核大小主要包括(3,3)和(5,5)。
(2)normalize属性表示是否对目标图像进行归一化处理。其中1表示需要,0表示不需要,不添加normalize时默认状态为需要。当进行归一化处理时,其处理与均值滤波相同,而当不进行归一化处理时,其像素值等于周围一定范围的像素点像素值的直接相加,很容易溢出,超过255即显示白色。
其代码如下:
#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图片
img = cv2.imread('C:/Users/CLH/Desktop/test3.JPG')
source = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 方框滤波
result = cv2.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()
(3)归一化处理后的图:
(4)不进行归一化处理的图:
由于在添加噪声时添加的噪声点过多,导致此时滤波处理后的图直接成白的了,我们将核矩阵大小设置为2×2,再出图。
1)核矩阵5×5
2)核矩阵2×2
4. 高斯滤波
图像高斯平滑也是邻域平均的思想对图像进行平滑的一种方法,在图像高斯平滑中,对图像进行平均时,不同位置的像素被赋予了不同的 权重。
(1)高斯滤波让临近的像素具有更高的重要度,对周围像素计算加权平均值,较近的像素具有较大的权重值。以3×3的邻域为例,均值滤波是对这九个数求平均,而高斯滤波是对这个九个数求加权平均,其中心思想是邻域中每个点离中心点的距离不一样,不应该像均值滤波一样每个点的权重一样,而是离中心点越近,权值越大。而每个点的权重就是高斯分布(也就是正态分布)。如下图示例所示,中心位置权重最高为0.4。
(2)Python中OpenCV主要调用GaussianBlur函数,如下:
dst = cv2.GaussianBlur(src, ksize, sigmaX)。其中,src表示原始图像,ksize表示核大小,sigmaX表示X方向方差。
如果sigma为非正数(负数或0)的话,就会根据ksize来自动计算sigma,计算公式为sigma = 0.3*((ksize-1)*0.5-1)+0.8。
(3)高斯滤波代码及结果如下:
#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图片
img = cv2.imread('C:/Users/CLH/Desktop/test3.JPG')
source = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 高斯滤波
result = cv2.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()
5. 中值滤波
(1)在一连串数字{1,4,6,8,9}中,数字6就是这串数字的中值。在图像中去3*3的矩阵,里面有9个像素点,我们将9个像素进行排序,最后将这个矩阵的中心点赋值为这九个像素的中值。
(2)OpenCV主要调用medianBlur()函数实现中值滤波。图像平滑里中值滤波的效果最好。dst = cv2.medianBlur(src, ksize),其中,src表示源文件,ksize表示核大小。核必须是大于1的奇数,如3、5、7等。
参考:[Python图像处理] 四.图像平滑之均值滤波、方框滤波、高斯滤波及中值滤波。
https://blog.csdn.net/Eastmount/article/details/82216380
均值滤波和中值滤波
https://blog.csdn.net/cjsh_123456/article/details/79261271