您的位置:首页 > 运维架构

OpenCV自学记录(4)——(一拳超人)图像处理基础(模版匹配、图形轮廓)

2020-04-21 19:12 295 查看

OpenCV自学记录(4)——图像处理基础(模版匹配、图形轮廓)

  • 2、模板匹配
  • 3、总结
  • 1、图形轮廓

    一个轮廓一般对应一系列的点。也就是图像中的一条直线。

    1.1 寻找轮廓:findContours()函数

    使用cv2.findContours()函数来查找检测物体的轮廓。

    contours, hierarchy = cv2.findContours(image, mode, method[, contours[, hierarchy[, offset ]]])

    参数意义
    image:寻找轮廓的图像,且为二值图(黑白图);
    mode:轮廓的检索模式,有四种:
    1、cv2.RETR_EXTERNAL表示只检测外轮廓
    2、 cv2.RETR_LIST检测的轮廓不建立等级关系
    3、 cv2.RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。
    4、cv2.RETR_TREE建立一个等级树结构的轮廓。
    method:轮廓的近似办法
    1、 cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1
    2、cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息
    3、cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法
    返回值
    cv2.findContours()函数返回两个值,一个是轮廓本身contours,还有一个是每条轮廓对应的属性hierarchy 。

    1.2 绘制轮廓:drawContours()函数

    OpenCV中通过cv2.drawContours在图像上绘制轮廓。

    cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset ]]]]])

    参数意义
    image:指明在哪幅图像上绘制轮廓;
    contours:轮廓本身,在Python中是一个list。
    contourIdx:指定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓。后面的参数很简单。其中thickness表明轮廓线的宽度,如果是-1(cv2.FILLED),则为填充模式。

    import cv2
    img = cv2.imread('02.jpg',0)    #读取图像
    ret, binary = cv2.threshold(img,127,255,cv2.THRESH_BINARY) #转为二值图
    #寻找轮廓
    contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
    # 为保留原始图像不变,复制一个图片用来绘制轮廓
    image = img.copy()
    # 在复制图上绘制轮廓
    cv2.drawContours(image, contours, -1, (0, 0, 255), 3)
    cv2.imshow("Original", img)
    cv2.imshow("image", image)
    cv2.waitKey(0)

    需要注意的是cv2.findContours()函数接受的参数为二值图,即黑白的(不是灰度图),所以读取的图像要先转成灰度的,再转成二值图

    参考:
    https://blog.csdn.net/weixin_40922285/article/details/102843938
    https://blog.csdn.net/sunny2038/article/details/12889059

    2、模板匹配

    模板匹配就是一项在一副图像中寻找与另一幅模板图像最匹配(相似)部分的技术。模板匹配不是基于直方图,而是通过在输入图像上滑动图像块,对实际图像快和输入图像进行匹配的一种匹配方法。模板类似于卷积操作中的卷积核

    2.1 模板匹配:matchTemplate()函数

    cv2.matchTemplate(image, templ, method, result=None, mask=None)

    参数意义
    image:待搜索图像
    templ:模板图像
    result:匹配结果
    method:计算匹配程度的方法。关于匹配方法,使用不同的方法产生的结果的意义可能不太一样,有些返回的值越大表示匹配程度越好,而有些方法返回的值越小表示匹配程度越好。
    1、CV_TM_SQDIFF 平方差匹配法:该方法采用平方差来进行匹配;最好的匹配值为0;匹配越差,匹配值越大。
    2、CV_TM_CCORR 相关匹配法:该方法采用乘法操作;数值越大表明匹配程度越好。
    3、CV_TM_CCOEFF 相关系数匹配法:1表示完美的匹配;-1表示最差的匹配。
    4、CV_TM_SQDIFF_NORMED 归一化平方差匹配法
    5、CV_TM_CCORR_NORMED 归一化相关匹配法
    6、CV_TM_CCOEFF_NORMED 归一化相关系数匹配法

    2.2 获取匹配结果函数:cv2.minMaxLoc()

    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(ret)

    参数说明
    min_val, max_val, min_loc, max_loc 分别表示最小值,最大值,以及最小值和最大值对应的图像中的位置,即是这个矩阵的最小值,最大值,并得到最大值,最小值的索引
    ret:cv2.matchTemplate()函数返回的矩阵

    实现代码与检测效果:
    以下代码实现一个对象的模版匹配

    import cv2
    
    img = cv2.imread('02.jpg', 0)
    # 载入模板
    template = cv2.imread('face.jpg', 0)
    h, w = template.shape[:2]
    res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF)
    #获取匹配结果函数
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    # 平方差匹配TM_SQDIFF或归一化平方差匹配TM_SQDIFF_NORMED,取最小值
    top_left = min_loc
    bottom_right = (top_left[0] + w, top_left[1] + h)
    # 画矩形
    cv2.rectangle(img, top_left, bottom_right, 255, 2)
    #显示图片
    cv2.imshow('model',img)
    cv2.waitKey()
    cv2.destroyAllWindows()


    多个对象的模板匹配代码

    import cv2
    import numpy as np
    
    img_rgb = cv2.imread('02.jpg')
    img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
    template = cv2.imread('face.jpg',0)
    w, h = template.shape[::-1]
    
    res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
    threshold = 0.8
    # 取匹配程度大于%80的坐标
    loc = np.where( res >= threshold)
    for pt in zip(*loc[::-1]):
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
    #保存图片
    #cv2.imwrite('res.png',img)
    #显示图片
    cv2.imshow('model',img_rgb)
    cv2.waitKey()
    cv2.destroyAllWindows()

    参考:
    https://blog.csdn.net/WZZ18191171661/article/details/91345166
    https://blog.csdn.net/qq_39507748/article/details/104598222

    3、总结

    本篇博客介绍了查找轮廓和绘制轮廓的代码,需要注意的是绘制轮廓是在原图上绘制的,为后续的图像处理常复制原图,在复制的图上绘制轮廓。
    模板匹配:可以进行单对象匹配和多对象匹配,还可以进行多尺度模板匹配

    图像处理的基础整理完毕,所有的Python代码已整理完毕,可直接运行(图像处理基础)——OpenCV自学记录系列,下一篇博客就可以利用OpenCV完成识别车牌号码的任务了。

    • 点赞
    • 收藏
    • 分享
    • 文章举报
    胖大海pyh 发布了9 篇原创文章 · 获赞 12 · 访问量 639 私信 关注
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: