目录
彩色空间
直方图均衡化
图像滤波
梯度
一、彩色空间
OpenCV 的颜色空间主要有 BGR、HSV、Lab等,cvtColor
函数可以让图像在不同颜色空间转换。例如通过将花的图像转换到 HSV 颜色空间,在HSV空间内过滤出只含有花瓣颜色的像素,从而提取出花瓣。
import numpy as np
import cv2
if __name__ == '__main__':
flower = cv2.imread('flower.jpeg', -1)
hsv = cv2.cvtColor(flower, cv2.COLOR_BGR2HSV)
lower_red = np.array([0, 20, 100])
upper_red = np.array([10, 255, 255])
mask = cv2.inRange(hsv, lower_red, upper_red)
res = cv2.bitwise_and(flower, flower, mask=mask)
images = np.concatenate((flower, res), axis=1)
cv2.imshow('flower', images)
cv2.waitKey()
cv2.destroyAllWindows()
二、直方图均衡化
通过调整图像的直方图调整图像的整体细节实现如下效果,下图左图是浑水鱼,右边清澈鱼。
import numpy as np
import cv2
if __name__ == '__main__':
fish = cv2.imread('fish.jpeg', -1)
b, g, r = cv2.split(fish)
bx, gx, rx = cv2.equalizeHist(b), cv2.equalizeHist(g), cv2.equalizeHist(r)
fish_enhance = cv2.merge((bx, gx, rx))
images = np.concatenate((fish, fish_enhance), axis=1)
cv2.imwrite('fish_enhance.jpeg', images)
cv2.imshow('fish_enhance', images)
cv2.waitKey()
cv2.destroyAllWindows()
三、图像滤波
图像滤波是在尽可能保留图像细节特征的条件下对目标图像的噪声进行抑制,是常用的图像预处理操作。平滑滤波也称为低通滤波,可以抑制图像中的灰度突变,使图像变得模糊,是低频增强的空间域滤波技术。盒式核是最简单的可分离低通滤波器核。盒式核结构简单,模板区域中各像素点的系数相同。OpenCV 提供了函数 cv.boxFilter()
可以实现直方图均衡化。
函数说明:
cv.boxFilter(src, ddepth, ksize[, dst[, anchor[, normalize[, borderType]]]]) → dst
简单的代码实现如下:
import cv2 as cv
if __name__ == '__main__':
img = cv.imread("Lena.png")
ksize = (5, 5)
imgBoxFilter = cv.boxFilter(img, -1, ksize=ksize)
cv.imshow("BoxFilter", imgBoxFilter)
key = cv.waitKey(0)
四、梯度
在图像处理中,梯度反映了像素值的最大变化率的方向,能够突出和提取边缘,常用于工业检测中产品缺陷检测和自动检测的预处理。
OpenCV 提供了三种梯度算子:Sobel、Scharr 和 Laplacian。Sobel 梯度算子是高斯平滑和微分求导的联合运算,抗噪声能力强。
Sobel 梯度算子很容易通过卷积操作 cv.filter2D 实现,OpenCV 也提供了函数 cv.Sobel 实现 Sobel 梯度算子。
函数说明:
cv.Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]]) → dst
我们用 Sobel 算子从 Lena 图像提取边缘,看看会产生什么样的效果吧。
实现代码如下:
import cv2 as cv
if __name__ == '__main__':
img = cv.imread("lena.png", flags=1)
imgGray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
SobelX = cv.Sobel(imgGray, cv.CV_16S, 1, 0) # 计算 x 轴方向
SobelY = cv.Sobel(imgGray, cv.CV_16S, 0, 1) # 计算 y 轴方向
absX = cv.convertScaleAbs(SobelX) # 转回 uint8
absY = cv.convertScaleAbs(SobelY) # 转回 uint8
SobelXY = cv.addWeighted(absX, 0.5, absY, 0.5, 0) # 用绝对值近似平方根
cv.imshow("Sobel gradient", SobelXY)
cv.waitKey(0)