第六章、图像金字塔、轮廓检测与模板匹配

基于Python的OpenCV学习

第六章、图像金字塔、轮廓检测与模板匹配

00_思维导图

在这里插入图片描述

01_cv2.pyrUp_cv2.pyrDown

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('AM.png')

# cv2.pyrUp(image)方法,实现对图像的向上采点,效果与放大图片相仿。
img_up = cv2.pyrUp(img)
# cv2.pyrDown(image)方法,实现对图像的向下采点,效果与缩小图片相仿。
img_down = cv2.pyrDown(img)

# 从三个图片的像素大小不难得出结论:
# cv2.pyrUp(image)方法实现图片的两倍放大。
# cv2.pyrDown(img)方法实现图片的一半缩小。
img_list = [img,img_up,img_down]
img_title = ['init','up','down']
for i in range(3):
    plt.subplot(1,3,i+1)
    plt.imshow(img_list[i])
    plt.title(img_title[i])

plt.show()
cv2.destroyAllWindows()
运行结果:

在这里插入图片描述

02_cv2.findContours

import cv2
img = cv2.imread('contours.png',cv2.IMREAD_GRAYSCALE)
# 图像二值化,cv2.findContours只有在二值化后的图像里才能发挥作用。
ret,img_thresh = cv2.threshold(img,127,255,cv2.THRESH_BINARY)

# cv2.findContours(image,mode,method)方法,对图片作轮廓处理,
# 返回两个数据对象,一个是图像的轮廓信息,一个是图像的轮廓层级。
contours,hierarchy = cv2.findContours(img_thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
# mode变量,文件检索模式,通常使用cv2.RETR_TREE,检索所有轮廓,重构轮廓的整个层级。
# method变量,轮廓逼近方法。
# 当method=cv2.CHAIN_APPROX_NONE时,保留轮廓的线条。
# 当method=cv2.CHAIN_APPROX_SIMPLE时,保留轮廓的终点。

03_cv2.drawContours

import cv2

img = cv2.imread('car.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,img_thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours,hierarchy = cv2.findContours(img_thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

# 绘制轮廓时一定要在图片的副本上进行,否则会直接改动原图。
# 从灰度图上得到轮廓,把轮廓画在原图上。
img2 = img.copy()
# cv2.drawContours(image,contours,hierarchy,color,width)方法,绘制轮廓。
result = cv2.drawContours(img2,contours,-1,(0,0,255),2)
# image表示绘制画板,contours表示轮廓信息。
# hierarchy表示绘制具体哪个层级的轮廓,当hierarchy=-1时绘制所有层级的轮廓。
# color变量为一个三元素列表,分别对应B、G、R的颜色强度。
# width表示线条宽度。

cv2.imshow('',result)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:

在这里插入图片描述

04_cv2.contoursArea_cv2.arcLength.py

import cv2
img = cv2.imread('car.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,img_thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)

contours,hierarchy = cv2.findContours(img_thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
# 详细解释一下cv2.findContours返回的轮廓信息contours,
# contours是一个长列表,包含了各个层级的轮廓。
# contours[0]表示第一个轮廓的信息,contours[1]表示第二个轮廓的信息…………

cnt = contours[0]
# cv2.contourArea(cnt)方法,返回轮廓的面积。
print(cv2.contourArea(cnt))
# cv2.arcLength(cnt,True)方法,返回轮廓的周长,True表示该轮廓是闭合轮廓。
print(cv2.arcLength(cnt,True))

05_cv2.approxPolyDP

import cv2
img = cv2.imread('contours2.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,img_thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours,hierarchy = cv2.findContours(img_thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = contours[0]

epsilon1 = 0.1 * cv2.arcLength(cnt,True)
# cv2.approxPolyDP(cnt,epsilon1,True)方法,返回轮廓的近似轮廓。
# 其中,cnt表示原轮廓,epsilon变量通常为原轮廓周长的系数倍。
# 当系数为0.01时,新轮廓与原轮廓基本保持一致,系数通常设置为0.1。
cnt2 = cv2.approxPolyDP(cnt,epsilon1,True)

img2 = img.copy()
result = cv2.drawContours(img2,[cnt2],-1,(0,0,255),2)
cv2.imshow('',result)
cv2.waitKey()
cv2.destroyAllWindows()

运行结果:

在这里插入图片描述

06_cv2.boundingRect

import cv2
img = cv2.imread('car.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours,h = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = contours[0]

# cv2.boundingRect(cnt)方法,返回轮廓矩形的左上角x、y坐标和宽度长度。
x,y,w,h = cv2.boundingRect(cnt)
# 那么,这个矩形的位置就可以确定了,
# 左上角的坐标是(x,y),右下角的坐标是(x+w,y+h)。

print(x,y,w,h)

07_cv2.rectangle

import cv2
img = cv2.imread('contours.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours,h = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = contours[0]

x,y,w,h = cv2.boundingRect(cnt)
# cv2.rectangle(img,sitex,sitey,color,width)方法,生成轮廓的近似矩形。
# sitex、sitey表示矩形的左上角、右下角坐标。
rect = cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),2)

cv2.imshow('',rect)
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述

08_cv2.minEnclosingCircle

import cv2
img = cv2.imread('contours.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours,h = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = contours[0]

# cv2.minEnclosingCircle(cnt)方法,返回两个对象。
# 一个是轮廓外接圆的原点坐标,一个是外接圆的半径。
(x,y),r = cv2.minEnclosingCircle(cnt)

09_cv2.circle

import cv2
img = cv2.imread('contours.png')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
contours,h = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = contours[0]

(x,y),r = cv2.minEnclosingCircle(cnt)
x = int(x)
y = int(y)
r = int(r)
# cv2.circle(img,(x,y),r,color,width)方法,绘制轮廓的外接圆。
circle = cv2.circle(img,(x,y),r,(0,0,255),2)
# (x,y)表示圆心的坐标,r表示外接圆半径,仅能取int类型。

cv2.imshow('',circle)
cv2.waitKey()
cv2.destroyAllWindows()
运行结果:

在这里插入图片描述

10_cv2.matchTemplate

import cv2
template = cv2.imread('face.jpg')
img = cv2.imread('lena.jpg')

# 若现在有两张图片,一张模板一张原图,模板跟原图的某个部分类似或者相同。
# cv2.matchTemplate(image,template,type)方法,实现模板匹配。
res = cv2.matchTemplate(img,template,cv2.TM_SQDIFF_NORMED)
# 若原图大小A*B,模板大小为a*b,则输出结果的矩阵大小为(A-a+1)*(B-b+1)。
# 当type=cv2.TM_SQDIFF:计算平方不同,计算出来的值越小,越相关。
# 当type=cv2.TM_CCORR:计算相关性,计算出来的值越大,越相关。
# 当type=cv2.TM_cCOEFF:计算相关系数,计算出来的值越大,越相关。
# 当type=cv2.TM_SQDIFF_NORMED:计算归—化平方不同,计算出来的值越接近0,越相关。
# 当type=cv2.TM_CCORR_NORMED:计算归—化相关性,计算出来的值越接近1,越相关。
# 当type=cv2.TM_CCOEFF_NORMED:计算归一化相关系数,计算出来的值越接近1,越相关。
# 尽量使用归一化模板匹配,通常使用cv2.TM_SQDIFF_NORMED即可解决绝大多数问题。

print(res.shape)
cv2.waitKey()
cv2.destroyAllWindows()

11_cv2.minMaxLoc

import cv2
template = cv2.imread('face.jpg')
img = cv2.imread('lena.jpg')
res = cv2.matchTemplate(img,template,cv2.TM_SQDIFF_NORMED)

# cv2.minMaxLoc(res)方法,返回模板匹配后的各种信息。
min_value,max_value,min_loc,max_loc = cv2.minMaxLoc(res)
# 较常用的数据是min_loc,确定的模板匹配的左上角的坐标点。
# 借助原图和目标的高度宽度,可以确定出模板匹配的具体范围。

(x,y) = min_loc
(h,w) = template.shape[:2]
rect = cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),2)
cv2.imshow('',rect)
cv2.waitKey()
cv2.destroyAllWindows()
运行结果:

在这里插入图片描述

图片素材

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值