图像金字塔&图像轮廓

高斯金字塔和拉普拉斯金字塔

图像金字塔,简单来说就是同一图像的不同分辨率的子图集合,把最大的图像放在底部,最小的放在顶部。
高斯金字塔的顶部图像中的每个像素值等于下一层图像中 5 个像素的高斯加权平均值,这样操作一次一个 MxN 的图像就变成了一个 M/2xN/2 的图像。这幅图像的面积就变为原来图像面积的四分之一,重复操作分辨率越低

使用函数  cv2.pyrDown(src , dst , dstsize ) 从一个高分辨率大尺寸的图像向上构建一个金子塔(尺寸变小,分辨率降低)

        src  输入图

        dst  输出图,深度会和来源图相同,尺寸会依输入图参数决定,

        dstsize   输出图的尺寸,通常,输出图的尺寸为: Size((src.cols+1)/2,(src.rows+1)/2) )

   缩小图像方法原理:

        对图像G_i进行高斯内核卷积

        将所有偶数行和列去除

img = cv2.imread('op.jpg')
down1 =cv2.pyrDown(img)
down2 =cv2.pyrDown(down1)
cv2.imshow('down1',down1)
cv2.imshow('down2',down2)
cv2.imshow('img',img)

 缩小


使用函数  cv2.pyrUp(src ,dst , dstsize)  从一个低分辨率小尺寸的图像向下构建一个金子塔(尺寸变大,但分辨率不会增加)

        放大图像方法原理:

        将图像在每个方向扩大为原来的两倍,新增的行和列以0填充

        使用先前同样的内核(乘以4)与放大后的图像卷积,获得 “新增像素”的近似值

img = cv2.imread('op.jpg')
up =cv2.pyrUp(img)
cv2.imshow('up',up)
cv2.imshow('img',img)


拉普拉斯金字塔可以由高斯金字塔计算得来,公式如下:

L i = G i PyrDown (PyrDown(Gi)   )     拉普拉金字塔的图像很多像素都是 0

img = cv2.imread('op.jpg')
down = cv2.pyrDown(img)
down_up =cv2.pyrUp(down)
la_l = img-down_up
cv2.imshow('la_l',la_l)


 图像轮廓

轮廓具有相同的颜色或者灰度。在形状分析和物体的检测和识别中很有用。
为了准确,要使用二值化图像。在寻找轮廓之前,要进行阈值化处理或者 Canny 边界检测。
查找轮廓的函数会修改原始图像,因此应该提前copy一份

轮廓检测方法

使用函数 cv2.findContours( img ,mode,method)     

返回值:contours(轮廓):是一个列表,里面存贮着图像中所有的轮廓,每一个轮廓都是一个numpy数组,包含对象边界点(x, y)的坐标)

        hierarchy:轮廓的层析结构

mode :轮廓检索模式

        RETR_EXTENAL:只检索最外面的轮廓

        RETR_LIST:检索所有轮廓,并保存到一条链表中

        RETR_CCOMP:检索所有轮廓并分为两层,外层是各部分外部边界,内层是空洞边界

        RETR_TREE:检索所有轮廓,并重构嵌套轮廓的整个层次        (这个用最多)

method:轮廓逼近方法

        CHAIN_APPROX_NONE:所有的边界点都会被存储,以Freeman链码方式输出轮廓

        CHAIN_APPOX_SIMPLE:压缩轮廓,将轮廓上的冗余点都去掉,只保留终点部分

注:此函数会修改原图,需要copy一个副本。。 


轮廓检测结果

把轮廓绘画到图像上

使用函数cv2.drawContours(img, contours, -1, (0,0,255), 2)

传入绘制图像(副本)、轮廓、轮廓索引:-1为所有图像、颜色模式、线条粗细

img = cv2.imread('oc.jpg')
gray =cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret ,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)

contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

img1 =img.copy()
res = cv2.drawContours(img1,contours,-1,(0,0,255),2)
cv2.imshow('img1',res)


 轮廓特征与近似

轮廓面积:使用函数 cv2.contourArea()

cnt = contours[-1]
area = cv2.contourArea(cnt)
print(area)


轮廓周长:使用函数 cv2.arcLength()

这个函数第二参数可以用来指定对象的形状是闭合的(True),还是打开的(一条曲线)

cnt = contours[-1]        #可以单独索引
perimeter = cv2.arcLength(cnt,True)
print(perimeter)


轮廓近似

将轮廓形状近似到由尽可能少的点组成的轮廓形状,新轮廓的点的数目由我们设定的准确度来决定

原理:

  使用函数 cv2.approxPolyDP(cnt,epsilon,True)

        cnt :传入轮廓

        epsilon :从原始轮廓到近似轮廓的最大距离,它是一个准确度参数(一般用周长的百分比)

     

img = cv2.imread('od.jpg')

gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = contours[-1]      #一个轮廓0就行,这里有其他微小轮廓用了-1
#绘制独立轮廓
img1 = img.copy()
img2 = img.copy()
img1 = cv2.drawContours(img1,[cnt],-1,(0,0,255),3)

epsilon = 0.01*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)
img2 = cv2.drawContours(img2,[approx],-1,(0,0,255),3)

res = np.hstack((img1,img2))
cv2.imshow('img',res)


 边界矩形

使用函数:  cv2.boundingRect()        得到x ,y,w,h
        cv2.rectangle( img, (x,y), (x +w,y+h), (0,255,0),  2  )
         x,y)为矩形左上角的坐标,(w,h)是矩形的宽和高
x,y,w,h = cv2.boundingRect(cnt)
img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)


最小外接圆

使用函数 cv2.minEnclosingCircle()         找到最小外接圆(圆心,半径)
(x,y),radius = cv2.minEnclosingCircle(cnt)
center = (int(x),int(y))
radius = int(radius)
img = cv2.circle(img,center,radius,(0,255,0),2)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

onlywishes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值