本文为《OpenCV计算机视觉实战》的课程笔记。
1 图像金字塔
1.1 基本概念

图像金字塔主要有两种:
1、高斯金字塔
2、拉普拉斯金字塔
1.1.1 高斯金字塔
1、向下采样法(缩小):长和宽都缩小2倍
- 用高斯核与 G i G_i Gi卷积
- 去除偶数行和偶数列
2、向上采样法(放大):长和宽都扩大2倍
- 将 G i G_i Gi在 x x x和 y y y方向都扩大为原来的两倍,新增像素用0填充,得到 G i ′ G_i' Gi′
- 将高斯核与 G i ′ G_i' Gi′进行卷积
1.1.2 拉普拉斯金字塔

1.2 金字塔制作方法
1.2.1 高斯金字塔
上采样:cv2.pyrUp(img)
下采样:cv2.pyrDown(img)
img = cv2.imread('./img/cat.jpg')
img = cv2.resize(img, (300, 300))
# 上采样
up = cv2.pyrUp(img)
# 下采样
down = cv2.pyrDown(up)
cv_show('up&down', np.hstack((img, down)))

从上图来看,经过上采样再经过下采样后,图像的色彩和清晰度都损失了。
1.2.2 拉普拉斯金字塔
对灰度图的处理效果:
img = cv2.resize(cv2.imread('./img/cat.jpg',cv2.IMREAD_GRAYSCALE),(300, 300))
down = cv2.pyrDown(img)
down_up = cv2.pyrUp(down)
l_1 = img - down_up[:797,:797]
cv_show('lap_1',l_1)

对彩色图像的处理效果:
img = cv2.resize(cv2.imread('./img/cat.jpg'), (300, 300))
down = cv2.pyrDown(img)
down_up = cv2.pyrUp(down)
l_1 = img - down_up[:797,:797,:]
cv_show('lap_1',l_1)
2 轮廓检测
2.1 图像轮廓检测方法
轮廓得是一个整体。
cv中的方法:
contours, hierarchy = cv2.findContours(img,mode,method)
mode:轮廓检测模式
RETR_EXTERNAL
:只检索最外面的轮廓RETR_LIST
:检索所有的轮廓,并将其保存到一条链表当中RETR_CCOMP
:检索所有的轮廓,并将他们组织为两层:顶层是各部分的外部边界,第二层是空洞的边界RETR_TREE
:检索所有的轮廓,并重构嵌套轮廓的整个层次(通常只用这个方法)
method:轮廓逼近方法
CHAIN_APPROX_NONE
:以Freeman链码的方式输出轮廓。CHAIN_APPROX_SIMPLE
:压缩水平的、垂直的和斜的部分,只保留他们的重点部分
以矩形举例,CHAIN_APPROX_NONE
输出矩形的四边,CHAIN_APPROX_SIMPLE
输出矩形的四个顶点。
为了更高的准确率,使用二值图像。
返回值:
- contours:轮廓信息,数据类型为列表
- hierarchy:见这篇博文
2.2 轮廓绘制方法
res = cv2.drawContours(src, contours, contours_index, color_mode, line_weight)
-
src:输入图像
-
countours:轮廓检测得到的轮廓
-
countours_index:轮廓索引,负数表示显示所有轮廓
一张图像中往往可以提取出多条轮廓线,轮廓线可能是闭合的也可能是开放的(这句话可能不是很严谨,意会一下)。
如图所示,封闭形状有内外两条轮廓线(图中标号为轮廓索引) -
color_mode:轮廓线使用的颜色
-
line_weight:轮廓线的粗细
注意,执行本方法后,执行结果会覆写src
!
2.2 轮廓检测
1、读入图像,并将图像转化为二值图。
img = cv2.resize(cv2.imread('./img/cat.jpg'),(300, 300))
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 173, 255, cv2.THRESH_BINARY)
cv_show('thresh',np.hstack((gray, thresh)))
回顾一下,这里cv2.threshold(gray, 173, 255, cv2.THRESH_BINARY)
是将超过阈值的像素点替换为255,否则替换为0,即像素值超过阈值的设置为白色,其余点设置为黑色(知识点见第3章)。

猫猫头顶部分和背景的区分度不是很好,可以预见根据这张灰度图得到的轮廓不会很理想。
2、获取轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
3、绘制轮廓
# 绘制轮廓
draw_img = img.copy()
res = cv2.drawContours(draw_img, contours, -1, (0,0,255),2)
cv_show('res',res)

效果果然不是很好,猫猫的外轮廓和背景连到一起了TAT。或许先加强一下灰度图的对比度效果会更好?回头研究一下。