代码
#读取
import cv2, math
import numpy as np
import matplotlib.pyplot as plt
## 定义图像目录
image_directory = 'D:\\PyDev\\CVHomework\\images\\'
# 图像读取
imgname = image_directory + 'lena.jpg'
img = cv2.imread(imgname)
# 图像显示在一个新的名字为'image'的窗口中,如果看不到,在任务栏中把窗口恢复后观察图像,在窗口中按任意键关闭窗口
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
1. 直方图均衡化
灰度均衡化
# 计算直方图
grayimg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 彩色图像转化为灰度图像
hist = cv2.calcHist([grayimg], [0], None, [256], [0, 256]) # 仅对 0 通道
# 显示直方图
r_hist = plt.hist(grayimg.ravel(), bins=256, color='b')
plt.xlim([0, 255])
plt.show()
# 显示灰度图像
cv2.imshow('grayimage',grayimg)
# 直方图均衡化
dstimg = cv2.equalizeHist(grayimg)
# 显示均衡化的图像
cv2.imshow('image',dstimg)
cv2.waitKey(0)
cv2.destroyAllWindows()
彩色直方图均衡化 - 1
# 图像读取
imgname = image_directory + 'lena.jpg'
img = cv2.imread(imgname)
# Python 中成对使用三个引号,可以写大段的跨行注释
"""
YUV色彩空间是把亮度(Luma)与色度(Chroma)分离,彩色电视采用的图像表示方法
“Y”表示亮度,也就是灰度值
“U”表示蓝色通道与亮度的差值
“V”表示红色通道与亮度的差值
对彩色图像进行直方图均衡化时,先将图像从BGR空间转到YUV空间,然后对亮度Y通道进行直方图均衡化,然后再转换回BGR空间
"""
img_yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
# equalize the histogram of the Y channel
img_yuv[:,:,0] = cv2.equalizeHist(img_yuv[:,:,0])
# convert the YUV image back to RGB format
img_output = cv2.cvtColor(img_yuv, cv2.COLOR_YUV2BGR)
cv2.imshow('Color input image', img)
cv2.imshow('Histogram equalized', img_output)
cv2.waitKey(0)
cv2.destroyAllWindows()
彩色均衡化 - 2
# 图像读取
imgname = image_directory + 'lena.jpg'
img = cv2.imread(imgname)
"""
OpenCV 中有HSV空间,和HSI空间比,取值范围不同: 0-180, 0-255, 0-255
先转换到HSV空间
在V通道进行直方图均衡化
再转换回BGR空间
"""
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# equalize the histogram of the V channel
hsv[:,:,2] = cv2.equalizeHist(hsv[:,:,2])
# convert back to BGR
img_output = cv2.cvtColor(hsv,cv2.COLOR_HSV2BGR)
cv2.imshow('Color input image', img)
cv2.imshow('Histogram equalized', img_output)
cv2.waitKey(0)
cv2.destroyAllWindows()
2. 图像平滑
2.1 平均
# 图像读取
imgname = image_directory + 'lena.jpg'
img = cv2.imread(imgname)
# 在5x5模版下进行图像平均, 该模版是 5x5个1,再除以25
blur = cv2.blur( img,(5,5))
# 显示原图像
cv2.imshow('srcimage',img)
# 显示结果图像
cv2.imshow('resimage',blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.2 高斯滤波
# 图像读取
imgname = image_directory + 'lena.jpg'
img = cv2.imread(imgname)
# 在5x5模版下进行图像平均, 该模版是 5x5个1,再除以25
blur = cv2.blur( img,(5,5))
# 显示原图像
cv2.imshow('srcimage',img)
# 显示结果图像
cv2.imshow('resimage',blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.3 中值滤波
# 中值滤波, 参数确定模版的大小:5x5
blur = cv2.medianBlur(img,5)
# 显示原图像
cv2.imshow('srcimage',img)
# 显示结果图像
cv2.imshow('resimage',blur)
# 等待按下一个键
cv2.waitKey(0)
# 模版增大 5-->9
blur = cv2.medianBlur(img,9)
cv2.imshow('resimage',blur)
# 等待按下一个键
cv2.waitKey(0)
# 模版增大 9-->15
blur = cv2.medianBlur(img,15)
cv2.imshow('resimage',blur)
# 等待按下一个键
cv2.waitKey(0)
# 关闭所有窗口
cv2.destroyAllWindows()
3. 图像梯度
# 图像读取
imgname = image_directory + 'lena.jpg'
bgrimg = cv2.imread(imgname)
img = cv2.cvtColor(bgrimg, cv2.COLOR_BGR2GRAY)
# Laplace 算子; 最后一个参数决定图像的深度, -1表示和原图像一样, cv2.CV_64F 64位浮点 cv2.CV_32F 32位浮点
laplacian=cv2.Laplacian(img,cv2.CV_64F)
# 参数1,0 为只在x方向求一阶导数,最大可以求2 阶导数。
sobelx=cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
# 参数0,1 为只在y方向求一阶导数,最大可以求2 阶导数。
sobely=cv2.Sobel(img,cv2.CV_64F,0,1,ksize=5)
#转换成uint8
abs_lap = cv2.convertScaleAbs( laplacian);
abs_sobelx = cv2.convertScaleAbs( sobelx);
abs_sobely = cv2.convertScaleAbs( sobely);
abs_sobel = cv2.addWeighted( abs_sobelx, 0.5, abs_sobely, 0.5, 0 );
# 同时显示原图像和结果图像
cv2.imshow('srcimage',img )
cv2.imshow('lapimage',abs_lap)
cv2.imshow('simage',abs_sobel)
cv2.waitKey(0)
cv2.destroyAllWindows()
4. 利用相关进行锐化
# 图像读取
imgname = image_directory + 'saturn.png'
bgrimg = cv2.imread(imgname)
img = cv2.cvtColor(bgrimg, cv2.COLOR_BGR2GRAY)
# 图像缩小
img = cv2.resize(img, (int(img.shape[1]/4), int(img.shape[0]/4)) )
# 定义模板
kernel = np.array([[0,-1,0],
[-1,5,-1],
[0,-1,0]])
# 空域相关操作进行滤波
sharpened = cv2.filter2D(img, -1, kernel)
cv2.imshow('srcimage',img )
cv2.imshow('shpimage',sharpened)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 图像读取
imgname = image_directory + 'saturn.png'
bgrimg = cv2.imread(imgname)
img = cv2.cvtColor(bgrimg, cv2.COLOR_BGR2GRAY)
# 图像缩小
img = cv2.resize(img, (int(img.shape[1]/4), int(img.shape[0]/4)) )
# 定义模板
kernel = np.array([[0,-1,0],
[-1,5,-1],
[0,-1,0]])
# 空域相关操作进行滤波
sharpened = cv2.filter2D(img, -1, kernel)
cv2.imshow('srcimage',img )
cv2.imshow('shpimage',sharpened)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 图像读取
imgname = image_directory + 'word.png'
bgrimg = cv2.imread(imgname)
img = cv2.cvtColor(bgrimg, cv2.COLOR_BGR2GRAY)
# 定义模板
kernel = np.array([[-1,-1,-1,-1,-1],
[-1, 2, 2, 2,-1],
[-1, 2, 8, 2,-1],
[-1, 2, 2, 2,-1],
[-1,-1,-1,-1,-1]]) / 8.0
# 空域相关操作进行滤波
sharpened = cv2.filter2D(img, -1, kernel)
cv2.imshow('srcimage',img )
cv2.imshow('shpimage',sharpened)
cv2.waitKey(0)
cv2.destroyAllWindows()
5. 利用相关进行滤波,检测不同的边
# 图像读取
imgname = image_directory + 'House.tiff'
bgrimg = cv2.imread(imgname)
img = cv2.cvtColor(bgrimg, cv2.COLOR_BGR2GRAY)
# 定义模板
kernel_emboss_1 = np.array([[0,-1,-1],
[1,0,-1],
[1,1,0]])/3.0
kernel_emboss_2 = np.array([[-1,-1,0],
[-1,0,1],
[0,1,1]])/3.0
kernel_emboss_3 = np.array([[1,0,0],
[0,0,0],
[0,0,-1]])
# 空域滤波
k1 = cv2.filter2D(img, cv2.CV_32F, kernel_emboss_1)
k2 = cv2.filter2D(img, cv2.CV_32F, kernel_emboss_2)
k3 = cv2.filter2D(img, cv2.CV_32F, kernel_emboss_3)
absk1 = cv2.convertScaleAbs( k1)+88
absk2 = cv2.convertScaleAbs( k2)+88
absk3 = cv2.convertScaleAbs( k3)+88
cv2.imshow('srcimage',img )
cv2.imshow('k1image',absk1)
cv2.imshow('k2image',absk2)
cv2.imshow('k3image',absk3)
cv2.waitKey(0)
cv2.destroyAllWindows()
知识点
3.1 背景知识
3.2基本灰度变换
空域滤波过程
- 平滑空间滤波器
- 目的:消除噪声、 去除太小的细节或将目标内的小间断连接起来实现模糊
- 方法:
- 平均
- 邻域平均法
- 加权邻域平均法
- 阈值邻域平均法
- 中值滤波
- 用一个含有奇数点的滑动窗口,将邻域中的像素按灰度级排序,取其中间值为输出像素
- 抑制图像随机脉冲噪声的同时不使边缘模糊。但对于线、尖顶等细节多的图像不宜采用中值滤波。
- 运算速度快,便于实时处理
- 图像锐化
- 边缘检测:
- 步骤:滤波、增强、检测
- Marr算法
- Canny边缘检测
- 边缘检测评价
- 平均