zoukankan      html  css  js  c++  java
  • openCV学习笔记(3)边缘检测和模板匹配

    1.canny边缘检测算法

    原理:https://www.cnblogs.com/mightycode/p/6394810.html

    1)使用高斯滤波,滤除噪声
    2)计算图像中每个像素点的梯度和方向
    3)应用非极大值抑制,以消除边缘带来的杂散影响
    4)应用双阈值,检测和确定真实和潜在边缘
    5)通过抑制孤立的弱边缘完成边缘检测

    import cv2 as cv
    import numpy as np
    #canny边缘检测算法
    def cvshow(img):
        cv.imshow("img",img)
        cv.waitKey(0)
        cv.destroyAllWindows()
    img = cv.imread("lena.jpg")
    img1 = cv.Canny(img,50,100)
    img2= cv.Canny(img,50,200)
    res = np.hstack((img1,img2))
    cvshow(res)#左边细节比右边多

     2.轮廓检测

    cv.findContours(img,mode,method)返回一个两个参数的列表 contours:检测到的轮廓   和  hierarchy:各个轮廓的继承关系

    一般我们使用在contours就可以了

    img:是你要检测的图像,必须是灰度图或者二值图像才行
    mode 轮廓模式
    。RETR_EXTERNAL 只检测最外面的轮廓
    。RETR_LIST 检测所有轮廓并保存到一张链表中
    。RETR_CCOMP 检测所有轮廓,并将他们分成两层,顶层是外部边界,第二层是空洞的边界
    。RETR_TREE 检测所有轮廓,并重构轮廓的嵌套层次
    mothod 轮廓靠近方法
    。CHAIN_APPROX_NONE 以Freeman链码方式输出轮廓 (就是保存了所有轮廓的点)
    。CHAIN_APPROX_SIMPLE 压缩水平的垂直的和斜线部分(就是将点简化连接成线)

    边缘检测的一般步骤:

    1.原图像

    2.转化到灰度图

    3.转化成二值图像

    4.使用findContours做边缘检测

    5.使用drawContours画出来

    比如这里我们读进来一张这张图片,对他进行边缘检测

    import cv2 as cv
    import numpy as np
    #canny边缘检测算法
    def cvshow(img):
        cv.imshow("img",img)
        cv.waitKey(0)
        cv.destroyAllWindows()
    img = cv.imread("graph.jpg")
    cvshow(img)
    gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
    thresh = cv.threshold(gray,150,255,cv.THRESH_BINARY_INV)[1]#简便方法
    cvshow(thresh)
    contours = cv.findContours(thres,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)[0]#简便方法 #contours,heriarchy
    = cv.findContours(thresh,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE) print(np.shape(contours)) res = cv.drawContours(img,contours,-1,(0,0,255),1) cvshow(res)

    结果:它一共检测到6个轮廓,这里你用cv.RETR_TREE的话会检测12个(内轮廓外轮廓)

     比如这是使用cv.RETR_TREE检测的

     这个是使用cv.RETR_EXTERNAL检测的

    在contours中包含了这些轮廓的坐标信息,我们可以利用这些坐标信息进一步画出该图像的外界矩形

    轮廓近似

    epsilon = 0.15*cv.arcLength(cnt,True)#修改数值,数值越小越接近边缘
    approx = cv.approxPolyDP(cnt,epsilon,True)
    draw_img = img.copy()
    res = cv.drawContours(draw_img,[approx],0,(0,0,255),3)
    imshow(res)

     外界矩形

    contours, hierarchy=cv.findContours(thresh, cv.RETR_TREE,cv.CHAIN_APPROX_NONE )
    draw_img = img.copy()
    res = cv.drawContours(draw_img,contours,-1,(0,0,255),2)
    cnt = contours[0]#cnt为第1个轮廓的位置点信息
    x,y,w,h = cv.boundingRect(cnt)//boundingRect计算轮廓的垂直边界最小矩形,矩形是与图像上下边界平行的
    img = cv.rectangle(img,(x,y),(x+w,y+h),(0,0,255),2)#画出矩形

    外接圆

    (x,y),radius = cv.minEnclosingCircle(cnt)#圆心和半径
    center = (int(x),int(y))
    radius = int(radius)
    img = cv.circle(img,center,radius,(0,0,255),2)

    模板匹配

    在这个版本的执行中如果报错depth == CV_8U || depth == CV_32F) && type == _templ.type() && _img.dims() <= 2 in function 'cv::mat 就执行cv.COLOR_BGR2RGB将你的照片转换为RGB

    模板匹配的6种方法

    # All the 6 methods for comparison in a list
    methods = ['cv.TM_CCOEFF', 'cv.TM_CCOEFF_NORMED', 'cv.TM_CCORR',
                'cv.TM_CCORR_NORMED', 'cv.TM_SQDIFF', 'cv.TM_SQDIFF_NORMED']

    使用方法

    res = cv.matchTemplate(people,template,cv.TM_CCOEFF)#参数为匹配对象,匹配模板,和匹配方法
    res.shape
    #结果为(A-a+1)*(B-b+1)   

    6种方法对比

    for meth in methods:
        img2 = people.copy()
        method = eval(meth)
        print(method)
        res = cv.matchTemplate(people,template,method)
        min_val,max_val,min_loc,max_loc = cv.minMaxLoc(res)#匹配的最小值,最大值,位置
        
        if method in [cv.TM_SQDIFF,cv.TM_SQDIFF_NORMED]:
            top_left = min_loc
        else :
            top_left = max_loc
        bottom_right = (top_left[0]+w,top_left[1]+h)
        
        cv.rectangle(img2,top_left,bottom_right,(0,0,255),2)
        plt.subplot(121),plt.imshow(res,cmap="gray")
        plt.xticks([]),plt.yticks([])
        plt.subplot(122),plt.imshow(img2,cmap="gray")
        plt.suptitle(meth)
        plt.show()

     多模板匹配

    img_rgb = cv.imread('images/mario.jpg')
    img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY)
    template = cv.imread('images/mario_coin.jpg',0)
    w, h = template.shape[::-1]
    res = cv.matchTemplate(img_gray,template,cv.TM_CCOEFF_NORMED)
    threshold = 0.85#达到相似程度,越大相似要求越高
    loc = np.where( res >= threshold)
    for pt in zip(*loc[::-1]):
        cv.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
    cvshow('res.png',img_rgb)
    plt.subplot(121),pltshow(img_gray)
    plt.subplot(122),pltshow(img_rgb)
    #loc[::-1]将输出的索引变换成x,y坐标,因为索引和x,y坐标是正好相反的,所以要对换下位置。然后再循环坐标,分别画出红色边界。

  • 相关阅读:
    Key-Value Memory Network
    Deep Mask Memory Network with Semantic Dependency and Context Moment for Aspect Level Sentiment Clas
    Deep Memory Network在Aspect Based Sentiment方向上的应用
    Deep Memory Network 深度记忆网络
    Self Attention 自注意力机制
    Attention基本公式及其变种
    *端策略优化算法(PPO)
    Policy Gradient 算法
    一本通 农场派对
    A
  • 原文地址:https://www.cnblogs.com/Truedragon/p/13019799.html
Copyright © 2011-2022 走看看