栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

图像轮廓的处理和计算

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

图像轮廓的处理和计算

文章目录
  • 1 什么是图像的轮廓
  • 2 查找轮廓
  • 3 绘制轮廓
  • 4 轮廓的周长和面积
  • 5 多边形逼近
  • 6 凸包
  • 7 外接矩形
  • 8 图像金字塔
    • 常见的两类图像金字塔
    • 拉普拉斯金字塔

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} ⎣⎢⎢⎢⎢⎡​14641​41624164​62436246​41624164​14641​⎦⎥⎥⎥⎥⎤​∗161​
  • 将 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)
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1001972.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号