OpenCv基础(五)
八、图像金字塔
- 图像金字塔是图像多尺度表达的一种,主要用于图像分割,是一种以多分辨率来解释图像的有效结构,也即图像金字塔是同一图像不同分辨率的集合
- 常见的两类金字塔:
- 高斯金字塔:用来下采样,主要的图像金字塔
- 拉普拉斯金字塔:用来从金字塔低层图像重建上层未采样图像,在数字图像处理中即预测参差,可以对图像还原,配合高斯金字塔一起使用
8.1 高斯金字塔
- 高斯金字塔:通过高斯平滑和亚采样获得一系列下采样图像
- 下采样
pyrDown(img):
利用高斯核卷积,将偶数行和列去除 - 上采样
pyrUp(img):
将图像在每个方向上扩大为两倍,新增的行列用0填充,再使用先前同样的内核与放大后的图像卷积,获得近似值
- 下采样
import cv2
import numpy as np
img = cv2.imread('../my_work/01.png')
print(img.shape)
# 分辨率减小的操作,下采样
dst_down = cv2.pyrDown(img)
print(dst.shape)
# 上采样
dst_up = cv2.pyrUp(dst)
cv2.imshow('img',img)
cv2.imshow('dst_down',dst_down)
cv2.imshow('dst_up',dst_up)
cv2.waitKey()
cv2.destroyAllWindows()
8.2 拉普拉斯金字塔
-
将下采样后的图像进行上采样,然后与之前还没有下采样的原图进行做差得到残差图,为还原图像做信息准备
-
也就是说,拉普拉斯金字塔是通过原图减去先缩小后放大的图像的一系列图像构成的,保留的是残差
- 拉普拉斯金字塔是由高斯金字塔构成的,没有专门的函数
- 拉普拉斯金字塔图像只像图像边缘,它的大部分元素是0,用于图像压缩
-
拉普拉斯金字塔计算公式:
拉普拉斯金字塔图像 = 原始图像 - pyrUp(pyrDown(原始图像))
import cv2
img = cv2.imread('../my_work/01.png')
# 第一层金字塔
dst = cv2.pyrDown(img)
dst = cv2.pyrUp(dst)
lap0 = img-dst
# 第二层金字塔
dst1 = cv2.pyrDown(dst)
dst1 = cv2.pyrUp(dst1)
lap1 = dst - dst1
cv2.imshow('img',img)
cv2.imshow('dst',dst)
cv2.imshow('lap0',lap0)
cv2.imshow('lap1',lap1)
cv2.waitKey()
cv2.destroyAllWindows()
九、图像直方图
- 图像直方图用来表示数字图像中的亮度分布,可借助该图了解需要如何调整亮度分布
- 横坐标:图像中各个像素点的灰度级
- 纵坐标:具有该灰度级的像素个数
x = [1,2,3,4,5],y = [3,1,2,1,2]
- 归一化直方图
- 横坐标:图像中各个像素点的灰度级
- 纵坐标:出现这个灰度级的概率=具有该灰度级的像素个数/像素总数
- 直方图术语:
dims:
需要统计的数目,如dims = 1,表示我们仅统计灰度值bins:
每个特征空间子区段的数目range:
统计灰度值的范围,一般为[0,255]
9.1 OpenCv统计直方图
calcHist(images,channels,mask,histSize,ranges[,hist[,accumulate]])
image:
原始图像channels:
指定通道,需要用中括号括起来,输入图像是灰度图像,值为[0],彩色图像可以是[0][1][2],分别对应BGRmask:
掩码图像,统计整幅图像的直方图,设为None,统计图像某一部分的直方图,需要掩码图像histSize:
bins的数量,要用中括号括起来ranges:
像数值范围accumulate:
累计标识,默认值为False,如果被设置为True。则直方图在开始分配时不会被清零- 该参数允许从多个对象中计算单个直方图,或者用于实时更新直方图
- 多个直方图的累计结果,用于对一组图像计算直方图
import cv2
img = cv2.imread('../my_work/01.png')
# 用opencv统计直方图
hist_b = cv2.calcHist([img],[0],None,[255],[0,255])
hist_g = cv2.calcHist([img],[1],None,[255],[0,255])
hist_r = cv2.calcHist([img],[2],None,[255],[0,255])
print(hist_b)
# 再利用matplotlib绘制
plt.plot(hist_b,color='b',label='blue')
plt.plot(hist_g,color='g',label='green')
plt.plot(hist_r,color='r',label='red')
plt.legend()
plt.show()
cv2.waitKey()
cv2.destroyAllWindows()
- 也可用matplotlib方式绘制直方图
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread('../my_work/01.png')
img = cv2.imread('../my_work/01.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 统计
plt.hist(gray.ravel(),bins=256,range=[0,255])
plt.show()
9.2 使用掩膜的直方图
- 如何生成掩膜:
- 先生成一个全黑的和原始图片大小一样的图片。mask = np.zeros(image.shape,np.unit8)
- 将想要的区域通过索引方式设置为255,mask[100:200,200:300] = 255
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread('../my_work/01.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
mask = np.zeros(gray.shape,np.uint8)
# 想要统计直方图的区域
mask[200:400,200:400] = 255
hist_mask = cv2.calcHist([gray],[0],mask,[256],[0,255])
hist_img = cv2.calcHist([gray],[0],None,[256],[0,255])
plt.plot(hist_mask)
plt.plot(hist_img)
plt.show()
# gray与gray做与运算结果还是gray,mask的作用:gray和gray先做与运算,再与mask做与运算
cv2.imshow('mask',cv2.bitwise_and(gray,gray,mask=mask))
cv2.waitKey()
cv2.destroyAllWindows()
9.3 直方图均衡化
- 通过拉伸像素强度的分布范围,使得在0-255灰阶上的分布更加均匀,提高了图像对比度,对比度较低的图像适合使用直方图均衡化来增强图像细节
- 原理:
- 1、计算累计直方图
- 2、将累计直方图进行区间转换,方法:×区间个数
- 3、在累计直方图中,概率相近的原始值,会被处理为相同的值
equalizeHist[src[,dst]]
src:
目标图像dst:
处理后图像
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('../my_work/01.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 将图片变亮
gray_bright = gray + 40
# 将图片变黑
gray_black = gray - 40
# 查看各自的直方图
hist_gray = cv2.calcHist([gray],[0],None,[256],[0,255])
hist_bright = cv2.calcHist([gray_bright],[0],None,[256],[0,255])
hist_black = cv2.calcHist([gray_black],[0],None,[256],[0,255])
# 画出直方图
plt.plot(hist_gray,label='gray')
plt.plot(hist_bright,label='bright')
plt.plot(hist_black,label='black')
plt.legend()
plt.show()
# 均衡化处理
black_equ = cv2.equalizeHist(gray_black)
bright_equ = cv2.equalizeHist(gray_bright)
# 查看均衡化之后的直方图
hist_black_equ = cv2.calcHist([black_equ],[0],None,[256],[0,255])
hist_bright_equ = cv2.calcHist([bright_equ],[0],None,[256],[0,255])
plt.plot(hist_black_equ,label='black_equ')
plt.plot(hist_bright_equ,label='bright_equ')
plt.legend()
plt.show()
cv2.imshow('to',cv2.hconcat((gray,gray_bright,gray_black)))
cv2.imshow('equ',cv2.hconcat((bright_equ,black_equ)))
cv2.waitKey()
cv2.destroyAllWindows()