OpenCV第七章模板匹配和图像分割
⼀.模板匹配
定义:让模板图像在输⼊图像中滑动逐像素遍历整个图像进⾏⽐较,查出与模板图像最匹配的部分。
单⽬标匹配
定义:输⼊图像中只存在⼀个可能匹配结果
基本格式如下:
result = cv2.matchTemplate(image,templ,method)
image为输⼊图像
templ为模板图像,要⼩于image
method为匹配⽅法,如下:
cv2.TM_SQDIFF:以⽅差结果为依据进⾏匹配。完全匹配时结果为零,否则为很⼤的值
cv2.TM_SQDIFF_NORMED:标准(归⼀化)⽅差匹配
cv2.TM_CCORR:相关匹配,将输⼊图像与模板图像相乘,乘积越⼤匹配程度越⾼,乘积为0匹配程度最低
cv2.TM_CCORR_NORMED:标准(归⼀化)相关匹配
cv2.TM_CCOEFF:相关系数匹配,将输⼊图像于其均值的相关性和模板图像与其均值的相关值进⾏匹配。1为完美匹配,-1并表⽰糟糕匹配,0表⽰没有任何相关性。
cv2.TM_CCOEFF_NORMED:标准(归⼀化)相关系数匹配
result为返回结果。当匹配⽅法为前两个时,匹配结果值越⼩匹配度越⾼,越⼤匹配度越低。当为后四个时值越⼩说明匹配度越低,反之则说明匹配度越⾼。
opencv中的cv2.minMaxLoc()函数⽤于处理匹配结果
minVal,maxVal,minLocmmaxLoc=cv2.minMaxLoc(src)
src是上⾯的matchTemplate()函数的返回结果
minVal(maxVal)为src中的最⼩值(最⼤值),不存在时可以为NULL(空值)
minLoc(MaxLoc)为src中最⼩值(最⼤值)的位置,不存在时可以为NULL
实例代码如下
import cv2
import numpy as np
import matplotlib. pyplot as plt
img1=cv2. imread( 'img/a.jpg')
cv2. imshow( ' original', img1)
rectangle函数opencvtemp=cv2. imread( 'img/b.jpg' )
cv2. imshow('template',temp)
img1gray=cv2. cvtColor(img1, cv2.COLOR_BGR2GRAY,dstCn=1)
tempgray=cv2. cvtColor(temp, cv2.COLOR_BGR2GRAY,dstCn=1)
h, w=tempgray.shape
res=cv2. matchTemplate(img1gray, tempgray,cv2.TM_SQDIFF)
plt.imshow(res,cmap = 'gray')
plt.title( 'Matching Result')
plt.axis('off')
plt. show()
min_val,max_val,min_loc,max_loc=cv2 .minMaxLoc(res)
top_left = min_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv2. imshow(' Detected Range ',img1)
cv2. waitKey(0)
原图像:
模板图像:
匹配结果:
本次⽤了cv2.TM_SQDIFF作为匹配⽅法,所以值越⼩匹配度就越⾼。⽤灰度图像格式显⽰匹配结果,所以图中颜⾊越深的位置匹配度越⾼
模板图像在原图当中的位置:
多⽬标匹配
定义:输⼊图像中存在多个可能的匹配以查象棋为例,查“卒象棋”:
模板图像:
代码如下:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img1=cv2. imread('img/d.jpg') #打开输⼊图像,默认为BGR格式
temp=cv2. imread('img/e.jpg') #打开模板图像
img1gray=cv2. cvtColor(img1, cv2. COLOR_BGR2GRAY, dstCn=1) #转换为单通道灰度图像
tempgray=cv2. cvtColor(temp,cv2. COLOR_BGR2GRAY , dstCn=1) #转换为单通道灰度图像
th, tw=tempgray.shape #获得模板图像的⾼度和宽度
img1h, img1w= img1gray. shape
res = cv2.matchTemplate(img1gray, tempgray, cv2.TM_SQDIFF_NORMED) #执⾏匹配操作
mloc=[] #⽤于保存符合条件的匹配位置
threshold = 0.02 #设置匹配度阈值
for i in range(img1h-th): #查符合条件的匹配结果位置
for j in range(img1w-tw):
if res[i][j]<=threshold: #保存⼩于阈值的匹配位置
mloc.append((j,i))
for pt in mloc:
cv2. imshow( ' result' ,img1) #显⽰结果
cv2.waitKey(0)
这种多⽬标匹配相较于上⾯的单⽬标的区别主要在于通过threshold,设置匹配度的阈值来筛选匹配位置。因为上⾯代码采⽤的模板匹配⽅法是cv2.TM_SQDIFF_NORMED,匹配结果越⼩匹配度越⾼。所以⼩于匹配度阈值的会被筛选出来。结果如下:
⼆.图像分割
本节采⽤分⽔岭算法和图像⾦字塔对图像进⾏分割的⽅法
使⽤分⽔岭算法分割图像
基本原理:将任意的灰度图像视为地形图表⾯,其中灰度值⾼的部分表⽰⼭峰和丘陵,灰度值低的部分表⽰⼭⾕。⽤不同的颜⾊的⽔(标签)填充每个独⽴的⼭⾕(局部最⼩值);随着⽔平⾯的上升,来⾃不同⼭⾕(具有不同颜⾊)的⽔将开始合并。为了避免出现这种现象,需要在⽔的汇合位置建造⽔坝;持续填充⽔和建造⽔坝,直⾄所有的⼭峰和丘陵都在⽔下。整个过程中建造的⽔坝将作为图像分割的依据。分⽔岭算法分割图像步骤:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论