(十一) 模糊
模糊操作方式:
均值模糊:一般用来处理图像的随机噪声
中值模糊:一般用来处理图像的椒盐噪声
自定义模糊:对图像进行锐化之类的操作
基于离散卷积、定义好每个卷积核、不同卷积核得到不同的卷积效果、模糊是卷积的一种表象
import cv2 as cv
import numpy as np
def blur(image):
"""
均值模糊
"""
# 参数(5,5):表示高斯矩阵的长与宽都是5
dst = cv.blur(image, (5, 5))
# 图二为均值模糊图
cv.imshow("blur", dst)
def median(image):
"""
中值模糊
"""
# 第二个参数是孔径的尺寸,一个大于1的奇数。
# 比如这里是5,中值滤波器就会使用5×5的范围来计算。
# 即对像素的中心值及其5×5邻域组成了一个数值集,对其进行处理计算,当前像素被其中值替换掉。
# 参考自:http://blog.csdn.net/sunny2038/article/details/9155893
dst = cv.medianBlur(image, 5)
# 图三为中值模糊
cv.imshow("median", dst)
def custom(image):
"""
自定义模糊
"""
# 定义一个5*5的卷积核
kernel = np.ones([5, 5], np.float32) / 25
dst = cv.filter2D(image, -1, kernel=kernel)
# 图四为效果图
cv.imshow("custom", dst)
# 读入图片文件
src = cv.imread('images/test.jpg')
# 图一为原图
cv.imshow('image 1', src)
blur(src)
median(src)
custom(src)
# 等待用户操作
cv.waitKey(0)
# 释放所有窗口
cv.destroyAllWindows()
模糊
(十二)高斯模糊
把要模糊的像素色值统计,用数学上加权平均的计算方法(高斯函数)得到色值,对范围、半径等进行模糊。
一些美颜软件、美颜相机上的磨皮和毛玻璃特效基本上都是用的高斯模糊,并且大部分图像处理软件中都有高斯模糊的操作,除此之外,高斯模糊还具有减少图像层次和深度的功能。
import cv2 as cv
import numpy as np
def clamp(pv):
"""防止颜色值超出颜色取值范围(0-255)"""
if pv > 255:
return 255
if pv < 0:
return 0
else:
return pv
#高斯噪声
def gaussian_noise(image):
"""高斯噪声"""
h, w, c = image.shape
for row in range(h):
for col in range(w):
# 获取三个高斯随机数
# 第一个参数:概率分布的均值,对应着整个分布的中心
# 第二个参数:概率分布的标准差,对应于分布的宽度
# 第三个参数:生成高斯随机数数量
s = np.random.normal(0, 20, 3)
# 获取每个像素点的bgr值
b = image[row, col, 0]
g = image[row, col, 1]
r = image[row, col, 2]
# 给每个像素值设置新的bgr值
image[row, col, 0] = clamp(b + s[0])
image[row, col, 0] = clamp(g + s[1])
image[row, col, 0] = clamp(r + s[2])
cv.imshow("noise", image)
# 读入图片文件
src = cv.imread('images/test.jpg')
#高斯噪声
gaussian_noise(src)
# 给图片创建毛玻璃特效
# 第二个参数:高斯核的宽和高(建议是奇数)
# 第三个参数:x和y轴的标准差
dst = cv.GaussianBlur(src, (5, 5), 15)
cv.imshow("gaussian", dst)
# 等待用户操作
cv.waitKey(0)
# 释放所有窗口
cv.destroyAllWindows()
高斯模糊
(十三)EPF
高斯模糊只考虑了权重,只考虑了像素空间的分布,没有考虑像素值和另一个像素值之间差异的问题,如果像素间差异较大的情况下(比如图像的边缘),高斯模糊会进行处理,但是我们不需要处理边缘,要进行的操作就叫做边缘保留滤波(EPF)。
import cv2 as cv
import numpy as np
def bi(image):
"""
色彩窗的半径
图像将呈现类似于磨皮的效果
"""
# image:输入图像,可以是Mat类型,
# 图像必须是8位或浮点型单通道、三通道的图像
# 0:表示在过滤过程中每个像素邻域的直径范围,一般为0
# 后面两个数字:空间高斯函数标准差,灰度值相似性标准差
dst = cv.bilateralFilter(image, 0, 60, 10);
cv.imshow('bi', dst)
def shift(image):
"""
均值迁移
图像会呈现油画效果
"""
# 10:空间窗的半径
# 50:色彩窗的半径
dst = cv.pyrMeanShiftFiltering(image, 10, 50);
cv.imshow('shift', dst)
src = cv.imread('images/test.jpg')
# 图一(原图)
cv.imshow('def', src)
# 图二(色彩窗的半径)
bi(src)
# 图三(均值迁移)
shift(src)
cv.waitKey(0)
cv.destroyAllWindows()
色彩窗的半径
均值迁移
(十三)图像直方图
由于其计算代价较小,且具有图像平移、旋转、缩放不变性等众多优点,广泛地应用于图像处理的各个领域,特别是灰度图像的阈值分割、基于颜色的图像检索以及图像分类。
图像主题内容与背景分离、图像分类、检索等。
注意:编写代码前需确保 matplotlib 库已安装,如未安装在命令行中输入:pip install matplotlib
- 直方图
import cv2 as cv
from matplotlib import pyplot as plt
def plot(image):
"""简单的图像直方图"""
plt.hist(image.ravel(), 256, [0, 256])
plt.show("直方图")
def image_his(image):
"""
这里生成的直方图是opencv 对图片
进行分割、图像检索等所需要的
"""
color = ('blue', 'green', 'red')
for i, color in enumerate(color):
hist = cv.calcHist([image], [i], None, [256], [0, 256])
plt.plot(hist, color=color)
plt.xlim([0, 256])
plt.show()
# 读入图片文件
src = cv.imread('images/test.jpg')
cv.imshow('def', src)
# 图一
plot(src)
# 图二
image_his(src)
cv.waitKey(0)
cv.destroyAllWindows()
简单的图像直方图
直方图
- 使用直方图调节对比度
import cv2 as cv
def equalHist(image):
"""直方图均衡化,图像增强的一个方法"""
# 彩色图片转换为灰度图片
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
# 直方图均衡化,自动调整图像的对比度,让图像变得清晰
dst = cv.equalizeHist(gray)
cv.imshow("equalHist", dst)
def clahe(image):
"""
局部直方图均衡化
把整个图像分成许多小块(比如按8*8作为一个小块),
那么对每个小块进行均衡化。
这种方法主要对于图像直方图不是那么单一的(比如存在多峰情况)图像比较实用
"""
# 彩色图片转换为灰度图片
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
# cliplimit:灰度值
# tilegridsize:图像切割成块,每块的大小
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
dst = clahe.apply(gray)
cv.imshow("clahe", dst)
src = cv.imread('images/test.jpg')
# 图一
cv.imshow("yt", src)
# 图二
equalHist(src)
# 图三
clahe(src)
cv.waitKey(0)
cv.destroyAllWindows()
直方图均衡化
局部直方图均衡化
注意:1、全图的直方图均衡化会导致对比度过度增强,所以在一些情况下应使用局部直方图均衡化;
2、opencv中直方图均衡化都是基于灰度图像的
- 对比图片相似度
import cv2 as cv
import numpy as np
def create_rgb_hist(image):
"""创建rgb 三通道直方图"""
h, w, c = image.shape
rgbHist = np.zeros([16 * 16 * 16, 1], np.float32)
bsize = 256 / 16
for row in range(h):
for col in range(w):
b = image[row, col, 0]
g = image[row, col, 1]
r = image[row, col, 2]
index = np.int(b / bsize) * 16 * 16 + np.int(g / bsize) * 16 + np.int(r / bsize)
rgbHist[np.int(index), 0] = rgbHist[np.int(index), 0] + 1
return rgbHist
def hist_compare(image1, image2):
hist1 = create_rgb_hist(image1)
hist2 = create_rgb_hist(image2)
# 巴氏距离比较,距离越小越相似
match1 = cv.compareHist(hist1, hist2, cv.HISTCMP_BHATTACHARYYA)
# 相关性比较,相关性越大越相似
match2 = cv.compareHist(hist1, hist2, cv.HISTCMP_CORREL)
# 卡方比较,越大越不相似
match3 = cv.compareHist(hist1, hist2, cv.HISTCMP_CHISQR)
print("巴氏距离:%s 相关性:%s 卡方:%s" % (match1, match2, match3))
hist_compare(cv.imread('images/test.jpg'), cv.imread('images/test.jpg'))
图1
结果 图2
结果 图3
结果
网友评论