轮廓检测与模板匹配

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

轮廓检测与模板匹配
注意:轮廓检测需要使⽤⼆值图像
img_gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
#为了更⾼的精确率使⽤⼆值图像,第⼀个返回值为127,即阈值,第⼆个为⼆值图像
_, img_bin = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
#cv2.findContours(img, mode, method),其中img为图像,mode为轮廓的检索⽅式,如检索所有轮廓、只检索最外⾯的轮廓等
#method为轮廓的逼近⽅法,cv2.CHAIN_APPROX_NONE:以freeman链码的⽅式输出轮廓,所有其他⽅法输出多边形
#cv2.CHAIN_APPROX_SIMPLE:压缩⽔平的、垂直的和斜的部分,只保留终点部分
#第⼆个返回值为轮廓
binary, contours, hie = cv2.findContours(img_bin, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
# 如果不⽤copy,将会把轮廓画到原图像,会改变原图像
img_draw = img1.copy()
#第三个参数为画第⼏个轮廓,-1为所有
img_ret = cv2.drawContours(img_draw, contours, -1, (0, 255, 0), 2)
cv2.imshow('img_ret', img_ret)
cv2.waitKey(0)
cv2.destroyAllWindows()
轮廓特征计算:
contours[i]表⽰第i个特征,计算特征时需要将每个轮廓单独拿出来
如计算第2个轮廓的⾯积
cv2.contourArea(contours[2])
计算周长
True表⽰是闭合的
cv2.arcLength(contours[2], True)
轮廓近似:
例如弧AB,连接AB得直线AB,找出弧AB中距离直线AB最远的点C,若C到直线AB的距离长度d⼩于所设定的阈值,则弧AB近似得直线AB 否则以C为分割点,分治
#epsilon相当于拟合程度,周长乘的数越⼩,和原来轮廓的拟合程度越⾼
epsilon = 0.01 * cv2.arcLength(contours[2], True)
img_appro = img1.copy()
#返回近似的轮廓
approx = cv2.approxPolyDP(contours[2], epsilon, True)
img_appro_ret = cv2.drawContours(img_appro, approx, -1, [0, 255, 0], 2)
cv2.imshow('img_appro_ret', img_appro_ret)
cv2.waitKey(0)
cv2.destroyAllWindows()
模板匹配:
模板匹配跟卷积原理很像,模板在原图像上从原点开始滑动,计算模板与图像被模板覆盖的地⽅的差别程度,这个差别程度的计算⽅法在opencv⾥有6种,
然后将每次的计算结果放到⼀个矩阵中,作为结果输出,假设原图像是A * B的⼤⼩,模板是a * b的⼤⼩,则输出的结果矩阵为(A - a + 1) * (B - b + 1)
第三个参数,匹配⽅法
使⽤不同的⽅法产⽣的结果的意义可能不太⼀样,有些返回的值越⼤表⽰匹配程度越好,⽽有些⽅法返回的值越⼩表⽰匹配程度越好。

关于参数 method:
CV_TM_SQDIFF 平⽅差匹配法:该⽅法采⽤平⽅差来进⾏匹配;最好的匹配值为0;匹配越差,匹配值越⼤。

CV_TM_CCORR 相关匹配法:该⽅法采⽤乘法操作;数值越⼤表明匹配程度越好。

CV_TM_CCOEFF 相关系数匹配法:1表⽰完美的匹配;-1表⽰最差的匹配。

CV_TM_SQDIFF_NORMED 归⼀化平⽅差匹配法
CV_TM_CCORR_NORMED 归⼀化相关匹配法
CV_TM_CCOEFF_NORMED 归⼀化相关系数匹配法
也可以⽤阿拉伯数字代替
img1 = cv2.imread('C:/Users/Dell/Downloads/1.jpg')
img_temp = cv2.imread('C:/Users/Dell/Downloads/4.jpg')
img_c = img1.copy()
#模板图⽚的长和宽
w, h = img_temp.shape[ : 2]
#返回匹配矩阵
ret = cv2.matchTemplate(img1, img_temp, 1)
#返回矩阵中的最⼩值、最⼤值、最⼩值坐标、最⼤值坐标
min_v, max_v, min_id, max_id = cv2.minMaxLoc(ret)
#求要画的矩形框的右下⾓坐标,如果是平⽅差匹配TM_SQDIFF或者归⼀化平⽅差匹配TM_SQDIFF_NORED使⽤min_id,否则使⽤max_id
right_low = (min_id[0] + w, min_id[1] + h)
cv2.rectangle(img_c, min_id, right_low, (0, 0, 255), 2)
cv2.imshow('img_c', img_c)
cv2.waitKey(0)
cv2.destroyAllWindows()
匹配多个对象:
img_temp = cv2.imread('C:/Users/Dell/Downloads/4.jpg')
img_c = img1.copy()
w, h = img_temp.shape[ : 2]
match_degree = cv2.matchTemplate(img_c, img_temp, 3)
#返回⼩于等于0.2的坐标,如果⾮平⽅差匹配,⽤⼤于等于
ret = np.where(match_degree <= 0.2)
for pt in zip(*ret[:: -1]):
right_low = (pt[0] + w, pt[1] + h)
cv2.rectangle(img_c, pt, right_low, (0, 0, 255), 1)
cv2.imshow('kk', img_c)
cv2.waitKey(0)
cv2.destroyAllWindows()。

相关文档
最新文档