OpenCV计算机视觉实战 | 第7章 金字塔与轮廓检测

本文详细介绍了OpenCV中的图像金字塔概念,包括高斯金字塔和拉普拉斯金字塔的构建方法,以及它们在图像缩放过程中的应用。同时,文章讲解了如何使用OpenCV进行图像轮廓检测,包括轮廓检测模式、轮廓逼近方法以及如何绘制轮廓。通过实例展示了在二值图像上进行轮廓检测的效果,探讨了改善轮廓检测效果的可能性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文为《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)))
image-20220213192419512
左:原图;右:上采样再下采样后的结果

从上图来看,经过上采样再经过下采样后,图像的色彩和清晰度都损失了。

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)
image-20220213204616817

对彩色图像的处理效果:

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)

image-20220213204728976image-20220213213348845

第二张:迭代3次后的效果

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:轮廓索引,负数表示显示所有轮廓

    一张图像中往往可以提取出多条轮廓线,轮廓线可能是闭合的也可能是开放的(这句话可能不是很严谨,意会一下)。

    image-20220214222200855
    如图所示,封闭形状有内外两条轮廓线(图中标号为轮廓索引)
  • 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章)。

image-20220214213934668

猫猫头顶部分和背景的区分度不是很好,可以预见根据这张灰度图得到的轮廓不会很理想。

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)
image-20220214214126011

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值