Advertisement

计算机视觉 实验四 Image_Processing5

阅读量:

目录

    • 3.6 图像金字塔与轮廓检测
      • 3.6.1 图像金字塔
  • Section 3.6.2: Laplacian Pyramid

  • Image Contour Analysis

  • What constitutes a contour?

  • A contour can be simply defined as the curve connecting all continuous points of equal intensity or color along an edge.

  • Contour analysis serves as a valuable tool for shape analysis and object detection/identification tasks.

  • Contour Features

  • Contour Approximation

  • Template Matching

  • six different comparison methods

  • multi-template matching approach

3.6 图像金字塔与轮廓检测

3.6.1 图像金字塔

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
复制代码
    import cv2  #opencv 读取进来为BGR格式
    import matplotlib.pyplot as plt
    import numpy as np
    
    #一个魔法指令,不需要采用plt.show()显示图像
    %matplotlib inline   
    
    
      
      
      
      
      
      
    
    代码解读
复制代码
    def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    
      
      
      
      
    
    代码解读
复制代码
    img = cv2.imread('images/lena.jpg')
    
    cv_show('lena',img)
    print(img.shape)
    print(img)
    
    
      
      
      
      
      
    
    代码解读
在这里插入图片描述
复制代码
    up = cv2.pyrUp(img) # cv2.pyrUp() 从一个低分辨率小尺寸的图像向下构建一个金子塔
    #尺寸变大,同时图片变糊
    #将图像在每个方向上扩大为原来的两倍,新增的行和列以0填充,再使用先前同样的内核(乘以4)与放大后的图像卷积,获得近似值
    cv_show("up",up)
    print(up.shape) #(600,600,3)
    
    
      
      
      
      
      
    
    代码解读
在这里插入图片描述
在这里插入图片描述
复制代码
    down = cv2.pyrDown(img) #cv2.pyrDown() 从一个高分辨率大尺寸的图像向上构建一个金字塔
    #尺寸变小,同时图片变糊,分辨率降低
    #pyrdown是pyrup将矩阵与高斯内核卷积,再将所有偶数列行和列去除
    cv_show('down', down)
    print(down.shape) #(150,150,3)
    
    
      
      
      
      
      
    
    代码解读
在这里插入图片描述
在这里插入图片描述
复制代码
    up2 = cv2.pyrUp(up) #再次pyrUp
    
    cv_show('up2',up2)
    print(up2.shape) #(1200,1200,3)
    
    
      
      
      
      
    
    代码解读
在这里插入图片描述
在这里插入图片描述
复制代码
    up = cv2.pyrUp(img)
    up_down = cv2.pyrDown(up) #在pyrUp基础上再pyrDown
    cv_show('img_up_down',up_down)
    print(up_down.shape)
    print(up_down)
    
    res = np.hstack((img,up_down))#虽然图像大小不变但是先pyrUp再pyrDown的图片变得模糊了
    
    cv_show('res',res)
    
    cv_show('img-updown',img-up_down) #原图和处理后的图像差值
    
    
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.6.2 拉普拉斯金字塔

复制代码
    down = cv2.pyrDown(img)
    up_down = cv2.pyrUp(down)
    res2 = img- up_down
    
    cv_show('Laplace',res2)#这个图色彩更加丰富,说明先pyrDown再pyrUp的损失更大
    
    
      
      
      
      
      
    
    代码解读
在这里插入图片描述

3.6.2 图像轮廓

什么是轮廓?

即为连接具有相同颜色或强度的所有连贯的点(沿着边界)所形成的曲线。这种曲线在形状分析方面发挥着重要作用,并被用来进行对象检测和识别等任务。

  • 以更高的精度,请使用二进制图像;为此,在发现边界之前,请应用阈值或Canny边缘检测。
  • 自OpenCV 3.2版本起始点以来, findContours()不再修改源图像.
  • 在OpenCV环境中, 发现边界类似于在暗背景下识别亮体; 因此,请记住,要识别的目标应为明亮物体,背景应为黑暗区域.
复制代码
    img = cv2.imread('images/test2.jpg')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #灰度化
    ret, thresh = cv2.threshold(gray, 127,255, cv2.THRESH_BINARY) #变成二值图像
    cv_show('thresh', thresh)
    
    
      
      
      
      
    
    代码解读
在这里插入图片描述
复制代码
    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) #全部轮廓,函数只保留终点部分
    
    
      
    
    代码解读
复制代码
    np.array(contours).shape #轮廓的大小
    
    
      
    
    代码解读
在这里插入图片描述
复制代码
    # 绘制轮廓
    # 使用cv.drawContours函数。只要有边界点,它也可以用来绘制任何形状。它的第一个参数是源图像,第二个参数是应该作为Python列表传递的轮廓
    # 第三个参数是轮廓的索引(在绘制单个轮廓时有用。要绘制所有轮廓,请传递-1),其余参数是颜色,厚度等等.
    # 注意需要copy,要不原图像会变。。。
    
    draw_img = img.copy()
    res = cv2.drawContours(draw_img, contours, -1, (0,0,255),2) #第三个参数如果填-1是找出所有的轮廓,是0就找出第一条轮廓
    cv_show('res', res)
    cv_show('img',img)
    
    
      
      
      
      
      
      
      
      
      
    
    代码解读
在这里插入图片描述
在这里插入图片描述
复制代码
    draw_img = img.copy()
    res = cv2.drawContours(draw_img, contours, 0, (0,255,0),2)
    cv_show('res', res)
    cv_show('img',img)
    
    
      
      
      
      
    
    代码解读
在这里插入图片描述
在这里插入图片描述
复制代码
    res = cv2.drawContours(img, contours, -1, (0,0,255),2) #直接对原图像进行操作,所以需要将原图像进行copy一下再进行操作
    cv_show('res', res)
    cv_show('img',img)
    
    
      
      
      
    
    代码解读
在这里插入图片描述
在这里插入图片描述
轮廓特征
复制代码
    cnt = contours[0]
    #print(contours)
    
    
      
      
    
    代码解读
复制代码
    # 面积
    area = cv2.contourArea(cnt) 
    
    #area1 = int(M["m00"]) #轮廓的面积也可以通过矩来表示
    print(area)
    
    
      
      
      
      
      
    
    代码解读
在这里插入图片描述
复制代码
    # 轮廓周长, True表示闭合的
    perimeter = cv2.arcLength(cnt,True)
    print(perimeter)
    
    
      
      
      
    
    代码解读
在这里插入图片描述
复制代码
    # 特征矩
    M = cv2.moments(cnt)
    #print( M )
    
    # 质心
    cx = int(M['m10']/M['m00'])
    cy = int(M['m01']/M['m00'])
    
    print(cx,cy)
    
    
      
      
      
      
      
      
      
      
      
    
    代码解读
在这里插入图片描述
轮廓近似
复制代码
    img2 = cv2.imread('images/star.png')
    
    img2_gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
    
    ret,thresh = cv2.threshold(img2_gray,127,255,0)
    
    contours,hierarchy = cv2.findContours(thresh, 1, 2)
    
    draw_img = img2.copy()
    res = cv2.drawContours(img2,contours, -1, (0,0,255),2)
    cv_show('res', res)
    
    cnt = contours[0]
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读
在这里插入图片描述
复制代码
    epsilon = 0.1*cv2.arcLength(cnt,True) 
    approx = cv2.approxPolyDP(cnt,epsilon,True)
    
    draw_img = img2.copy()
    res = cv2.drawContours(draw_img, [approx], -1, (0,255,0),2)
    cv_show('res', res)
    
    
      
      
      
      
      
      
    
    代码解读
在这里插入图片描述
模板匹配

基于卷积神经网络的方法在模式识别中表现优异。该算法通过将二维核在原始图像上以起始点为基础进行滑动操作,在图像上被该核覆盖的部分进行特征提取。具体而言,在OpenCV框架下提供了六种差异度计算方法,并将每一步骤所得结果存入预设大小矩阵作为最终输出结果。假设输入图像尺寸为A×B,则输出矩阵尺寸应为(A−a+1)×(B−b+1),其中a×b表示核的尺寸参数。

复制代码
    # 模板匹配
    img = cv2.imread('images/lena.jpg',0)
    template = cv2.imread('images/face.jpg',0)
    h, w = template.shape[:2]
    
    
      
      
      
      
    
    代码解读
复制代码
    img.shape
    
    
      
    
    代码解读
在这里插入图片描述
复制代码
    template.shape
    
    
      
    
    代码解读
在这里插入图片描述

采用平方差异度量(TM_SQDIFF),其结果数值低则表示数据点间关联性强。
通过余弦相似度(TM_CCORR)衡量数据间的相似程度,则结果数值越高表示相似程度越高。
使用皮尔逊相关系数(TM_CCOEFF)评估变量间的关系强度,则其结果数值越大反映变量间关联性越高。
采用归一化的平方差异度量(TM_SQDIFF_NORMED),其结果数值趋近于零表明数据高度一致。
通过归一化的余弦相似度(TM_CCORR_NORMED)衡量数据间的相似程度,则其结果数值接近于1则表示高度相似性。
使用归一化的皮尔逊相关系数(TM_CCOEFF_NORMED),其结果数值趋近于1则显示变量间的紧密关系。

参考链接:https://docs.opencv.org/2.4/doc/tutorials/imgproc/histograms/template_matching/template_matching.html

列表中所有的6种比较方法
复制代码
    methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
            'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']
    
    
      
      
    
    代码解读
复制代码
    res = cv2.matchTemplate(img,template,cv2.TM_SQDIFF)
    print(res.shape)  
    
    
      
      
    
    代码解读
在这里插入图片描述
复制代码
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    
    
      
    
    代码解读
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
复制代码
    img = cv2.imread('images/lena.jpg',0)
    img2 = img.copy()
    template = cv2.imread('images/face.jpg',0)
    
    w, h = template.shape[::-1]
    
    # 列表中所有的6种比较方法
    methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
            'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']
    
    for meth in methods:
    img = img2.copy()
    method = eval(meth)
    # 应用模板匹配
    res = cv2.matchTemplate(img,template,method)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    
    # 如果方法是TM_SQDIFF或TM_SQDIFF_NORMED,则取最小值
    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
        top_left = min_loc
    else:
        top_left = max_loc
        
    bottom_right = (top_left[0] + w, top_left[1] + h)
    cv2.rectangle(img,top_left, bottom_right, 255, 2)
    
    plt.subplot(121),plt.imshow(res,cmap = 'gray')
    plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
    plt.subplot(122),plt.imshow(img,cmap = 'gray')
    plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
    plt.suptitle(meth)
    plt.show()
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
多对象的模板匹配

当我们需要寻找频繁出现的目标时, OpenCV中的cv.minMaxLoc()函数无法返回全部匹配位置.因此,在此情况下我们建议采用阈值化方法来解决这个问题.

复制代码
    img_rgb = cv2.imread('images/mario.jpg')
    img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
    template = cv2.imread('images/mario_coin.jpg',0)
    w, h = template.shape[::-1]
    
    res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
    
    # 取匹配程度大于80%的坐标
    threshold = 0.8
    loc = np.where( res >= threshold)
    img_rgb2 = img_rgb.copy()
    for pt in zip(*loc[::-1]):  #*号表示可选参数
    cv2.rectangle(img_rgb2, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
    #cv2.imwrite('res.png',img_rgb)
    cv_show('img_rgb',img_rgb2)
    
    #res = np.stack((img_rgb,img_rgb2))
    #cv_show('res',res)
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
    代码解读
在这里插入图片描述

全部评论 (0)

还没有任何评论哟~