实验一:灰度变化
代码:
import cv2
import numpy as np
def liner_trans(org,k,b=0):
"""
灰度变化
:param img:
:param k: k>1时 实现灰度数值的拉伸,0<k<1 时 实现灰度数值的压缩,
k=-1 b=255 实现灰度数值的反转
:param b:灰度值
:return:
"""
# 计算灰度的线性变化映射表
translist=[(np.float32(x)*k+b) for x in range(256)]
print("映射表",translist)
# 需要转化为np.array
transTable=np.array(translist)
# 将查出[0,255]的灰度值进行调整,并指定数据类型为uint8
transTable[transTable > 255] = 255
transTable[transTable < 0] = 0
transTable = np.round(transTable).astype(np.uint8)
# 使用openCV的look up table 修改图片的灰度值
return cv2.LUT(org,transTable)
if __name__ == '__main__':
im=cv2.imread('data/mok.png')
cv2.imshow('org',im)
# 反转
# img=liner_trans(im,-1,255)
# cv2.imshow("invsion",img)
# 灰度拉伸
# img = liner_trans(im, 1.2)
# cv2.imshow("graystretch", img)
# 灰度压缩
img = liner_trans(im, 0.8)
cv2.imshow("graycompress", img)
cv2.waitKey()
cv2.destroyAllWindows()
运行:
1.1 灰度反转
# 反转
img=liner_trans(im,-1,255)
cv2.imshow("invsion",img)
1.2 灰度拉伸
# 灰度拉伸
img = liner_trans(im, 1.2)
cv2.imshow("graystretch", img)
1.3 灰度压缩
# 灰度压缩
img = liner_trans(im, 0.8)
cv2.imshow("graycompress", img)
?1.4 gamma矫正
代码:
def gamma_tarns(img,gamma):
"""
伽马矫正
:param img:
:param gamma: 伽马值
:return:
"""
#先归一化到1 做伽马计算 再还原到[0,255]
gammaList=[np.power(x/255.0,gamma)*255.0 for x in range(256)]
#将数据转换为np.array 并且指定数据类型为uint8
gammaTable=np.round(np.array(gammaList).astype(np.uint8))
print(gammaTable)
# 使用openCV 的look up table函数修改图像的灰度值
return cv2.LUT(img,gammaTable)
1.4.1 使用伽马值为0.5的变化 实现对暗部的压缩 亮部的拉伸
1.4.2 使用伽马值为2的变化 实现对亮部的压缩 暗部的拉伸
?
?实验二:直方图
2.1 直方图的显示?
代码:
import cv2
import matplotlib.pyplot as plt
#读取并显示图像
im=cv2.imread('data/1.png',0)
cv2.imshow("org",im)
#绘制灰度图像的直方图
plt.hist(im.ravel(),256,[0,256])
plt.show()
cv2.waitKey()
cv2.destroyAllWindows()
运行:
? ? ? ? ? ? ? ?原图灰度图? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 灰度图直方图?
?2.2 直方图均衡化
?代码:
import cv2
import matplotlib.pyplot as plt
#读取并显示图像
im=cv2.imread('data/1.png',0)
cv2.imshow("org",im)
#绘制灰度图像的直方图
# plt.hist(im.ravel(),256,[0,256])
# plt.show()
# 调用OpenCV的直方图均衡化API
im_equl=cv2.equalizeHist(im)
cv2.imshow('equal',im_equl)
# 显示原图像的直方图
plt.subplot(2,1,1)
plt.hist(im.ravel(),256,[0,256],label="org")
plt.legend()
# 显示均衡化图像的直方图
plt.subplot(2,1,2)
plt.hist(im_equl.ravel(),256,[0,256],label="equalize")
plt.legend()
plt.show()
cv2.waitKey()
cv2.destroyAllWindows()
运行:
? ? ? ? ? ? ? ?原图灰度图? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?原图像的直方图
?
2.3 彩色直方图
代码
import cv2
import numpy as np
import matplotlib.pyplot as plt
def imageHist(img,type):
'''
彩色直方图
:param img: 通道数据
:param type: 用于判断传入的是那个通道
:return:
'''
# 判断传递进来的是那个通道
if type == 31: # 传入蓝色通道
color = (255,0,0)
winName = 'B Hist'
elif type == 32: # 绿色通道
color = (0, 255, 0)
winName = 'G Hist'
else:
color = (0, 0, 255)
winName = 'R Hist'
# 计算和绘制直方图
hist = cv2.calcHist([img],[0],None,[256],(0.0,255.0)) # 计算直方图
minV,maxV,minL,maxL = cv2.minMaxLoc(hist) # 获取最大值和最小值,并且获取对应的下标
print(minV,maxV,minL,maxL)
histImage = np.zeros([256,256,3],np.uint8) # 新建图像的模板,用于直方图的绘制
for h in range(256):
intenormal = int(hist[h] * 256 / maxV) # 为了避免超出取值范围
cv2.line(histImage,(h,256),(h,256-intenormal),color)
cv2.imshow(winName,histImage)
if __name__ == '__main__':
im = cv2.imread('data/1.png', 1)
cv2.imshow('im',im)
channels = cv2.split(im) # 分割通道
# print(channels)
for i in range(3):
print(channels[i])
imageHist(channels[i],i+31)
cv2.waitKey()
cv2.destroyAllWindows()
考点:分割通道 channels = cv2.split(im) ?# 分割通道
?运行:?
? ? ? ? ?? ?? 实验三:空间滤波
比较 :均值滤波 高斯滤波? 中值滤波
3.1 均值滤波
代码:
import cv2
import numpy as np
def avg(img,size):
"""
均值滤波
:param img: 待处理的图像
:param size: 滤波器尺寸
:return:
"""
avgImg=cv2.blur(img,size)
cv2.imshow("avgImg",avgImg)
def gaussian(img,size):
"""
高斯滤波
:param img: 待处理的图像
:param size: 滤波器尺寸
:return:
"""
gaussianImg=cv2.GaussianBlur(img,size,0)
cv2.imshow("gaussianImg", gaussianImg)
def media(img,size):
"""
中值滤波
:param img: 待处理的图像
:param size: 滤波器尺寸
:return:
"""
mediaImg=cv2.medianBlur(img,size)
cv2.imshow("mediaImg", mediaImg)
def sharpen(img):
"""
图像锐化
:param img:
:return:
"""
#定义一个锐化算子
M=np.array([
[0,-1,0],
[-1,9,-1],
[-1,-1,-1]
])/4.0
#进行滤波处理
im_s=cv2.filter2D(img,-1,M)
cv2.imshow('im_s',im_s)
if __name__ == '__main__':
# im=cv2.imread('data/6.png',1)
# cv2.imshow('im',im)
# 均值滤波
# avg(im,(5,5))
#高斯滤波
# gaussian(im,(5,5))
# 中值滤波
# media(im,5)
#图像锐化
im=cv2.imread('data/09.png',1)
cv2.imshow('im',im)
sharpen(im)
cv2.waitKey()
cv2.destroyAllWindows()
均值滤波:
# 均值滤波
# avg(im,(5,5))
?高斯滤波:
#高斯滤波
gaussian(im,(5,5))
中值滤波:
# 中值滤波
media(im,5)
图像锐化:
#图像锐化
im=cv2.imread('data/09.png',1)
cv2.imshow('im',im)
sharpen(im)
实验四:?图像二值化
4.1 简单二值化:
代码
import cv2
def simple(img):
'''
简单二值化
:param img:
:return:
'''
'''
cv2.threshold() 二值化
参数:
第一个 待处理的图像
第二个 阈值
第三个 颜色值
第四个 二值化的类型
THRESH_BINARY 黑白二值
THRESH_BINARY_INV 黑白的反转
THRESH_TRUNC 得到的图像多为像素值
THRESH_TOZERO 高于阈值时设置255 低于阈值不做处理
THRESH_TOZERO_INV 低于阈值时设置255 高于阈值不做处理
返回值
第一个是阈值
第二个是图像
'''
ret,thread1 = cv2.threshold(img,172,255,cv2.THRESH_BINARY)
ret,thread2 = cv2.threshold(img,172,255,cv2.THRESH_BINARY_INV)
ret,thread3 = cv2.threshold(img,172,255,cv2.THRESH_TRUNC)
ret,thread4 = cv2.threshold(img,172,0,cv2.THRESH_TOZERO)
ret,thread5 = cv2.threshold(img,172,255,cv2.THRESH_TOZERO_INV)
cv2.imshow("thread1",thread1)
cv2.imshow("thread2",thread2)
cv2.imshow("thread3",thread3)
cv2.imshow("thread4",thread4)
cv2.imshow("thread5",thread5)
运行:
if __name__ == '__main__':
im = cv2.imread('data/lena.jpg', 0)
cv2.imshow('im',im)
simple(im)
# auto(im)
cv2.waitKey()
cv2.destroyAllWindows()
?
?4.2 自适应阈值
代码
def auto(img):
ret,thread1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
'''
adaptiveThreshold() 自适应阈值
参数:
第一个 待处理的图像
第二个 像素值的上限
第三个 自适应的方式
ADAPTIVE_THRESH_MEAN_C 领域内的均值
ADAPTIVE_THRESH_GAUSSIAN_C 领域内像素点的加权,权重为一个高斯窗口
第四个 赋值的方法
第五个 设定领域的大小(一个正方形领域)
第六个 阈值等于均值或者加权值减去这个常数
'''
thread2 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,5,2)
thread3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
cv2.imshow('thread1',thread1)
cv2.imshow('thread2',thread2)
cv2.imshow('thread3',thread3)
运行:
if __name__ == '__main__':
im = cv2.imread('data/lena.jpg', 0)
cv2.imshow('im',im)
# simple(im)
auto(im)
cv2.waitKey()
cv2.destroyAllWindows()
?
?
实验五: 形态学运算
5.1 腐蚀
代码:
import cv2
import numpy as np
def corrode():
"""
腐蚀
:return:
"""
# 读取图像并进行二值化处理
im=cv2.imread('data/7.png',cv2.IMREAD_UNCHANGED)
cv2.imshow('im',im)
# 设置卷积核 生成一个5*5 全部为1 的矩阵
kernrl=np.ones((5,5),np.uint8)
# 图像的腐蚀
erosion=cv2.erode(im,kernrl)
cv2.imshow('erosion',erosion)
cv2.waitKey()
cv2.destroyAllWindows()
if __name__ == '__main__':
corrode()
运行:
5.2 膨胀
代码:
def expand():
"""
膨胀
:return:
"""
# 读取图像并进行二值化处理
im = cv2.imread('data/7.png', cv2.IMREAD_UNCHANGED)
cv2.imshow('im', im)
# 设置卷积核 生成一个5*5 全部为1 的矩阵
kernrl = np.ones((5, 5), np.uint8)
# 图像的膨胀
dest = cv2.dilate(im,kernrl)
cv2.imshow('dest', dest)
cv2.waitKey()
cv2.destroyAllWindows()
if __name__ == '__main__':
# corrode()
expand()
运行
?5.3 闭/开运算
代码:
def closepration():
"""
闭运算
:return:
"""
# 读取图像并进行二值化处理
im = cv2.imread('data/7.png', cv2.IMREAD_UNCHANGED)
cv2.imshow('im', im)
'''
getStructuringElement() 用于构造一个特定大小和相撞的结构元素,用于形态学处理
参数1:
MORPH_RECT 矩形
MORPH_CROSS 交叉型
MORPH_ELLIPSE 椭圆型
'''
kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(5,5 ))
dest=cv2.morphologyEx(im,cv2.MORPH_CROSS,kernel) #morphologyEx 该函数可以方便对图像进行一系列形态学运算 cv2.MORPH_CROSS 闭运算
# dest = cv2.morphologyEx(im, cv2.MORPH_OPEN, kernel) # cv2.MORPH_OPEN 开运算
cv2.imshow("dest",dest)
cv2.waitKey()
cv2.destroyAllWindows()
运行;闭运算
|