本案例为计算机视觉课程【第二章】图像处理基础的配套案例。
图像处理一般指数字图像处理。 数字图像是指用工业相机、摄像机、扫描仪等设备经过拍摄得到的一个大的二维数组,该数组的元素称为像素,其值称为灰度值。
图像处理技术一般包括图像运算、图像几何变换、形态学处理等方面。
本节介绍图像运算的相关内容。
图像运算指以图像为单位进行的搡作。运算的结果是一幅其灰度分布与原来参与运算图像灰度分布 不同的新图像。
具体的运算主要包括算术和逻辑运算,它们通过改变像素的值来得到图像增强、仿射等效果。
首先加载一张图像。
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread("./input/sea.jpg")
img_rgb = img[:,:,::-1] # 将图像转换为RGB
plt.imshow(img_rgb)
plt.show()
对图像进行加法运算:图像各像素加100
M = np.ones(img.shape,dtype="uint8")*100# 与image大小一样的全100矩阵
added = cv2.add(img,M) # 将图像image与M相加
added_rgb = added[:,:,::-1] # 将图像转换为RGB
plt.imshow(added_rgb)
plt.show()
接着对图像进行减法运算: 原图像每个像素都减去50,小于0的按0处理。
M = np.ones(img.shape,dtype="uint8")*50 # 与image大小一样的全50矩阵
subtracted = cv2.subtract(img,M) # 将图像image与M相减
subtracted_rgb = subtracted[:,:,::-1] # 将图像转换为RGB
plt.imshow(subtracted_rgb)
plt.show()
对图像进行点乘运算:图像的每个像素值乘以3。
M = np.ones(img.shape,dtype="uint8")*3
multiply = cv2.multiply(img, M)
multiply_rgb = multiply[:,:,::-1] # 将图像转换为RGB
plt.imshow(multiply_rgb)
plt.show()
对图像进行点除运算:图像的每个像素值除以3。
M = np.ones(img.shape,dtype="uint8")*3
divide = cv2.divide(img, M)
divide_rgb = divide[:,:,::-1] # 将图像转换为RGB
plt.imshow(divide_rgb)
plt.show()
image1 = cv2.imread("./input/sea.jpg") # 加载图像1
image1_rgb = image1[:,:,::-1] # 将图像转换为RGB
plt.imshow(image1_rgb)
plt.show()
image2 = cv2.imread("./input/tree.jpg") # 加载图像2
image2_rgb = image2[:,:,::-1] # 将图像转换为RGB
plt.imshow(image2_rgb)
plt.show()
然后对两幅图像做乘法运算。
multiply_2 = cv2.multiply(image1, image2) # 两个图像相乘,图像像素大小要相同
multiply_2_rgb = multiply_2[:,:,::-1] # 将图像转换为RGB
plt.imshow(multiply_2_rgb)
plt.show()
两个图像的交集可以表示为:dst
= src1 & src2
。
dst
:目标图像
sc1
:图像1
sc2
: 图像2
bitwise_and = cv2.bitwise_and(image1,image2)
bitwise_and = bitwise_and[:,:,::-1] # 将图像转换为RGB
plt.imshow(bitwise_and)
plt.show()
两个图像的并集为:dst
= src1 | src2
。
bitwise_or = cv2.bitwise_or(image1,image2)
bitwise_or = bitwise_or[:,:,::-1]
plt.imshow(bitwise_or)
plt.show()
图像的非:dst
= - src
bitwise_not = cv2.bitwise_not(image1)
bitwise_not = bitwise_not[:,:,::-1]
plt.imshow(bitwise_not)
plt.show()
两个图像的异或:dst
= src1 ^ src2
。
bitwise_xor = cv2.bitwise_xor(image1,image2)
bitwise_xor = bitwise_xor[:,:,::-1]
plt.imshow(bitwise_xor)
plt.show()
下面介绍RGB图像转换为HSV图像。
首先加载图像。
img = cv2.imread("./input/tree.jpg")
img = img[:,:,::-1] # 将图像转换为RGB
plt.imshow(img)
plt.show()
将RGB图像转换为HSV图像。
hsv_image = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
# HSV_image = HSV_image[:,:,::-1] # 将图像转换为RGB
plt.imshow(hsv_image)
plt.show()
接着介绍RGB图像转换为HLS图像。
hls_image = cv2.cvtColor(img, cv2.COLOR_RGB2HLS)
plt.imshow(hls_image)
plt.show()
img = cv2.imread("./input/bread.jpg")
img = img[:,:,::-1]
plt.imshow(img)
plt.show()
接着对图像进行平移操作。按照向左平移100,向下平移50操作。
img_grey = cv2.imread("./input/bread.jpg",0) # 读入灰度图片
rows,cols = img_grey.shape
m = 100 ; n = 50 # 平移的长度
M = np.float32([[1,0,m],[0,1,n]])
translation = cv2.warpAffine(img,M,(cols,rows)) # 平移
plt.imshow(translation)
plt.show()
再对原始图像进行缩放操作。宽度放大2倍,长度放大1.5倍。
resize = cv2.resize(img,None,fx =2 ,fy = 1.5) # 宽度放大2倍,长度放大1.5倍
plt.imshow(resize)
plt.show()
最后对原始图像进行旋转操作。
将图像相对于中心旋转90度而不进行任何缩放。
M = cv2.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),90,1)
rotation = cv2.warpAffine(img,M,(cols,rows))
plt.imshow(rotation)
plt.show()
# 随机选取出原图像中四个点的坐标
pts1 = np.float32([[56, 65],[368 ,52] , [28 ,387],[389 ,390]] )
# 给定经过透视变换后,上述四个点的新的坐标
pts2 = np.float32([[0,0], [300,0],[0,300],[300,300]])
# 根据转换前后的四对点的坐标,计算出变换矩阵
M = cv2.getPerspectiveTransform(pts1,pts2)
dst = cv2.warpPerspective(img ,M, (500,900)) # (500,900)是输出图像的大小
plt.imshow(dst)
plt.show()
img = cv2.imread("./input/flower.jpg")
img = img[:,:,::-1]
plt.imshow(img)
plt.show()
对图像进行均值平滑。
blur=cv2.blur(img, ksize = (5,5)) # ksize: 均值算子的尺寸,Size(宽,高)
plt.imshow(blur)
plt.show()
gaussian_blur = cv2.GaussianBlur(img, ksize = (25,25), sigmaX = 9)
plt.imshow(gaussian_blur)
plt.show()
medianblur = cv2.medianBlur(img, ksize = 11)
# int类型的ksize,孔径的线性尺寸(aperture linear size).
# 注意这个参数必须是大于1的奇数,比如:3,5,7,9 ...
plt.imshow(medianblur)
plt.show()
双边滤波是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折衷处理,达到保边去噪的目的。
具有简单、非迭代、局部处理的特点。
双边滤波之所以能够达到保边去噪的滤波效果,是因为滤波器由两个函数构成:一个函数是由几何空间距离决定滤波器系数,另一个是由像素差值决定滤波器系数。
bilateral_filter = cv2.bilateralFilter(img, d = 23,sigmaColor = 11,sigmaSpace = 13)
plt.imshow(bilateral_filter)
plt.show()
img = cv2.imread("./input/earth.jpg")
img = img[:,:,::-1]
plt.imshow(img)
plt.show()
接下来对图像进行腐蚀处理。
kernel = np.ones((3,3),np.uint8)
# kernel: 腐蚀操作的核。当为 NULL 时,表示的是使用参考点位于中心,大小 3×3 的核。
erosion = cv2.erode(img,kernel,iterations = 1)
# iteration的值为整数,它的值越高,图像的模糊程度(腐蚀程度)就越高。二者呈正相关关系
plt.imshow(erosion)
plt.show()
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,5))
dilate = cv2.dilate(img,kernel,iterations = 1)
plt.imshow(dilate)
plt.show()
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(10,10))
opening = cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)
plt.imshow(opening)
plt.show()
img = cv2.imread("./input/bread.jpg")
img = img[:,:,::-1]
plt.imshow(img)
plt.show()
接下来对图像进行闭运算处理。
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(10,10))
close = cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel)
plt.imshow(close)
plt.show()
img = cv2.imread("./input/flower.jpg")
img = img[:,:,::-1]
plt.imshow(img)
plt.show()
接着用Canny边缘检测处理图像。
# canny(): 边缘检测
img1 = cv2.GaussianBlur(img,(3,3),0)
canny = cv2.Canny(img1, 50, 150)
plt.imshow(canny)
plt.show()
img = cv2.imread("./input/sea.jpg")
img = img[:,:,::-1]
plt.imshow(img)
plt.show()
接下来绘制原始图片的直方图。
plt.hist(img.ravel(),256,[0,256]);
plt.show()
在其他用法,如进行基于颜色的图像检索时,我们需要的是BGR直方图。
绘制原理类似,统计时使用cv2.calcHist()函数。
color = ('b','g','r')
for i,col in enumerate(color):
histr = cv2.calcHist([img],[i],None,[256],[0,256])
plt.plot(histr,color = col)
plt.xlim([0,256])
plt.show()
img_grey = cv2.imread("./input/sea.jpg",0)
dst = cv2.equalizeHist(img_grey)
plt.imshow(dst)
plt.show()
绘值均衡化后的图像的直方图。
plt.hist(dst.ravel(),256,[0,256]);
plt.show()