1、图像金字塔定义
图像金字塔就是将图像组合成像金字塔一样的形状,比如原来的图像是1600*900,现在将它变换为1200*750的图像,在金字塔越上面就会越小。那么一张图像就会有多种形式,在以后如果做特征提取,可能不知有一种方法进行特征提取,可能需要对金字塔图像都要做特征提取。
- 高斯金字塔
- 拉普拉斯金字塔
1.1 高斯金字塔
高斯金字塔,向下采样法,缩小:
如图所示,这是一个高斯卷积核,还有一个归一化的操作(1/16)。
将图像与高斯内核近图像卷积,然后将偶数行列都去掉,这就是使用了高斯金字塔方法进行了下采样。
高斯金字塔,向上采样法,放大:
上采样,比如一个像素点加上三个0由1*1变成了2*2,然后再进行高斯内核的图像卷积,完成了上采样,补充值就是拿0填充。
2、金字塔制作方法
如何在OpenCV中执行第一节中的操作呢?
首先读进来一张图像:
img=cv2.imread("AM.png")
cv_show(img,'img')
print (img.shape)
打印结果:(442, 340, 3)
进行上采样操作:
up=cv2.pyrUp(img)
cv_show(up,'up')
print (up.shape)
pyr就是金字塔的所写,pyrUp顾名思义就是金字塔上采样,打印结果:(884, 680, 3)。图像变大了一些,这里就不展示了
下采样:
down=cv2.pyrDown(img)
cv_show(down,'down')
print (down.shape)
打印结果:(221, 170, 3)
如果先进行上采样在进行下采样,会和原始图片一样吗?
应该是不一样的,因为上采样是拿0进行填充的,代码:
up=cv2.pyrUp(img)
up_down=cv2.pyrDown(up)
cv_show(img-up_down,'img-up_down')
结果就不展示了,大家可以自己跑一下
2.1 拉普拉斯金字塔
拉普拉斯金字塔的制作方法稍微有点特别:
这里的Gi表示的是输入,后面的表示先进行下采样再进行上采样的结果,Gi减去这个结果,然后每一层都是这样做的。
如图,G0是第一层的原始图像,先经过低通滤波和下采样,然后经过上采样,原始图像再减去上采样的结果,第二层也是同样的做法,只不过第二层的原始输入是第一层的输出,后面以此类推。
当然在OpenCV实现:
down=cv2.pyrDown(img)
down_up=cv2.pyrUp(down)
l_1=img-down_up
cv_show(l_1,'l_1')
打印结果:
3、图像轮廓检测
函数:cv2.findContours(img,mode,method),model和method参数
mode:轮廓检索模式
- RETR_EXTERNAL :只检索最外面的轮廓;
- RETR_LIST:检索所有的轮廓,并将其保存到一条链表当中;
- RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界;
- RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次;
method:轮廓逼近方法
- CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。
- CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分,也就是,函数只保留他们的终点部分。
实际上在轮廓检索模式中,我们就使用最后一个就可以了。
怎样进行轮廓检测:
为了更高的准确率,使用二值图像:
img = cv2.imread('contours.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
cv_show(thresh,'thresh')
- 读取图像
- 灰度处理
- 二值处理(大于127的全部为255,小于127的全部为0,在前面已经讲过二值处理)
- 打印
打印结果:
计算轮廓信息:
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
contours:轮廓点,轮廓信息
hierarchy:层级信息
绘制轮廓:
#传入绘制图像,轮廓,轮廓索引,颜色模式,线条厚度
# 注意需要copy,要不原图会变。。。
draw_img = img.copy()
res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)
cv_show(res,'res')
将原始图像进行深度复制的原因是,因为drawContours会将原始图像上进行更改。
解释一下drawContours参数意思,draw_img是需要画轮廓的原始图,contours是原始图包含的轮廓信息,-1表示所有的轮廓都画出来,(0,0,255)分别表示bgr,就是画轮廓用什么颜色,这里就是用的纯红色,最后一个2是轮廓的线条宽度。