图像轮廓的处理和计算

1 什么是图像的轮廓

  • 图像的轮廓指的是同一个颜色的连续点曲线。
  • 轮廓是分析物体形状和检测识别的重要指标
  • 使用Canny等操作对图片进行二值化操作
  • 画轮廓是会修改原图

2 查找轮廓

  • cv2.findContours(image,mode,method)
  • mode查找模式:
      
    RETR_EXTERNAL = 0 只检测外轮廓
    RETR_LIST = 1 检测所有轮廓,不存在等级关系
    RETR_CCOMP = 2 每层最多检测2级,从小到大,从里到外
    RETR_TREE = 3 按照树形存储轮廓,从大到小,从右到左
  • method轮廓的近似方法:
      CHAIN_APPROX_NONE保存轮廓上的所有点
      CHAIN_APPROX_SIMPLE:只存储边缘的对角点,存储信息少,比较常用
  • 返回值参数:
      返回轮廓和层次。contours,hierarchy
import cv2
import numpy as np

img = cv2.imread('imgs/a.jpg')

# 把突变转为单通道的黑白照片
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 二值化处理:返回图片和阈值
max_value, img = cv2.threshold(img, 150,255,cv2.THRESH_BINARY)

# 查找轮廓,返回轮廓和阶级
contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 打印轮廓
print(contours)
# 打印图片
cv2.imshow('轮廓', img)

cv2.waitKey(0)

cv2.waitKey(0)

3 绘制轮廓

  • 通过查找轮廓findContours我们可以得到这个图像返回的轮廓
  • 使用cv2.drawContours(image,contours,contourldx,color)画出轮廓
        contours:轮廓点
        contourldx:想绘制轮廓图像的标号。 -1 为默认所有图像
#绘画轮廓,轮廓会直接修改原图
cv2.drawContours(img,contours,-1,(0,0,255))

4 轮廓的周长和面积

  • 查找轮廓之后,可能得到多个轮廓,通过周长和面积对这些轮廓进行筛选
  • 得到图像的轮廓,通过面积和周长来分析这个图像的具体特征
  • cv2.contourArea(contours):计算面积
  • cv2.arcLength(curve, closed):计算周长
      curve:表示轮廓
      closed:表示这个轮廓是否闭合
#计算第一个图的面积
cv2.contourArea(contours[0])
#计算轮廓的周长
cv2.arcLength(contours[0],True)

5 多边形逼近

  • 由于找到的轮廓图像非常多,可能过于复杂不平滑,故意使用**cv2.approxPolyDP()**对轮廓进行近似处理
  • 多边形逼近使用Douglas-Peucker算法进行处理
  • 首先设置一个阈值,在找到的目标两点之间遭到最远切线之间的距离,如果这个距离小于阈值,即可近似处理
  • cv2.approxPolyDP(curve, epsilon, closed)
       curve:多边形的轮廓
       epsilon:dp算法的阈值
       closed:是否闭合
import cv2
import numpy as np

img = cv2.imread('imgs/a.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
maxvlues, img = cv2.threshold(img, 150,255,cv2.THRESH_BINARY)
contours,hi = cv2.findContours(img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#使用多边形逼近来处理图片,大于20的点可以近似处理
approx = cv2.approxPolyDP(contours[1], 20, True)

#画出这个轮廓
cv2.drawContours(img,[approx],0,(0,255,0))

cv2.imshow('a',img)

cv2.waitKey(0)

6 凸包

  • 为了对轮廓的图像进行改进,使用凸包对轮廓进一步的描述,使得所有连续三个点的角度小于180度
  • 得到一个大概的轮廓
  • cv2.convexHull(contours[1]) 传入轮廓即可

import cv2
import numpy as np
#读取照片
img = cv2.imread('imgs/a.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
maxvlues, img = cv2.threshold(img, 150,255,cv2.THRESH_BINARY)
contours,hi = cv2.findContours(img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

#计算凸包,传入某一个轮廓的列表
hull = cv2.convexHull(contours[1])

#画出凸包轮廓
cv2.drawContours(img,[hull],0,(0,255,0))

cv2.imshow('a',img)

cv2.waitKey(0)

7 外接矩形

  • 最小外接矩形:使用最小的框
  • rect = cv2.minAreaRect(contours[1])
       传入某一个具体的轮廓
       得到一个元组:矩阵的起始坐标,长款,矩形的旋转角度
  • 还需要计算出矩阵的各个点的坐标: box = cv2.boxPoints(rect)
  • 像素都是整型,还需要转化成整型
import cv2
import numpy as np

# 读取图片的地址
img = cv2.imread('imgs/a.jpg')
# 讲图片转为灰色图片
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 对图片的像素进行二值化处理
maxvlues, img = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY)
# 找到图片的所有轮廓
contours, hi = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 轮廓返回的是图片是各块像素的元组,存储在contours中,本文使用的关键像素是contours[1]


# 最小矩阵的生成
rect = cv2.minAreaRect(contours[1])

# 计算矩阵4个点的坐标
box = cv2.boxPoints(rect)

# 由于像素都是整数,所以对坐标还需要转成整型
box = np.int0(box)

# 绘制最小矩阵
cv2.drawContours(img, [box], 0, (255, 0, 0))

cv2.imshow('a', img)

cv2.waitKey(0)
  • 最大外接矩形:使用最大的框
  • cv2.boundingRect(contours[1])
  • 得到的就是4个点的坐标
  • 使用rectangle画上矩阵的坐标
import cv2
import numpy as np

# 读取图片的地址
img = cv2.imread('imgs/a.jpg')
# 讲图片转为灰色图片
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 对图片的像素进行二值化处理
maxvlues, img = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY)
# 找到图片的所有轮廓
contours, hi = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 轮廓返回的是图片是各块像素的元组,存储在contours中,本文使用的关键像素是contours[1]


# 最大外接矩阵的生成
x,y,w,h = cv2.boundingRect(contours[1])

# 绘制最大外接矩阵
cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)

cv2.imshow('a', img)

cv2.waitKey(0)

8 图像金字塔

 图像金字塔是同一张图片不同分辨率的集合。

  • 对于一张高分辨率的图片,通过压缩成分辨率低的图片。

常见的两类图像金字塔

  1. 高斯金字塔
       通过使用高斯平滑和亚采样(subsampling)来获取一系列的下采样图像
    G i G_i Gi = [ 1 4 6 4 1 4 16 24 16 4 6 24 36 24 6 4 16 24 16 4 1 4 6 4 1 ] ∗ 1 16 \begin{bmatrix} 1 &4&6&4&1 \\4 &16&24&16&4\\6 &24&36&24&6 \\4 &16&24&16&4 \\1 &4&6&4&1 \\ \end{bmatrix}*\frac{1}{16} 1464141624164624362464162416414641161
  • G i G_i Gi与高斯内核卷积
  • 将所有二代偶数行列去掉
  1. 下采样会减少图片的分辨率:cv2.pyrDown(img)
import cv2

# 读取图片的地址
img = cv2.imread('imgs/66.jpg')

#高斯金字塔进行下采样
dst = cv2.pyrDown(img)
#分别查看原图和缩小之后的图
cv2.imshow('a', img)
cv2.imshow('b', dst)

cv2.waitKey(0)
  1. 向上采样:将图片放大,放大4倍,用0来补充
  2. 然后使用内卷进行卷积
import cv2

# 读取图片的地址
img = cv2.imread('imgs/66.jpg')

#高斯金字塔进行上采样
dst = cv2.pyrUp(img)
#分别查看原图和放大之后的图
cv2.imshow('a', img)
cv2.imshow('b', dst)

cv2.waitKey(0)

拉普拉斯金字塔

使用高斯金字塔对图片先缩小向下采样,然后向上采样。
  • 使用原图减去改变之后的图片即可得到丢失的数据,即拉普拉斯金字塔
import cv2

# 读取图片的地址
img = cv2.imread('imgs/66.jpg')


#先缩小2倍
dst = cv2.pyrDown(img)


# 再放大2倍
dst = cv2.pyrUp(dst)
#相减之后的差集即拉普拉斯金字塔
dst = img-dst


cv2.imshow('a', img)
cv2.imshow('b', dst)

cv2.waitKey(0)
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值