zoukankan      html  css  js  c++  java
  • opencv学习记录之图像轮廓之三

    轮廓拟合

    矩形包围轮廓

    1,函数cv2.boundingRect()能够绘制轮廓的矩形边界

    retval = cv2.boundingRect( array)

    retval 表示返回矩形边界左上角顶点的坐标值及矩形边界的宽和高 , 也可以是4个返回值形式 

        x , y ,w ,h  = cv2.boundingRect( array)

    array 是灰度图像或轮廓

    然后使用函数cv2.drawContours()来绘制矩形包围框

     1 import cv2 
     2 import numpy as np                                                               
     3 o = cv2.imread("cc.bmp")
     4 cv2.imshow("original" , o) 
     5 gray = cv2.cvtColor(o , cv2.COLOR_BGR2GRAY)
     6 ret , binary = cv2.threshold(gray , 127 , 255 ,cv2.THRESH_BINARY)
     7 contours , hierarchy = cv2.findContours(binary , cv2.RETR_LIST ,
     8         cv2.CHAIN_APPROX_SIMPLE)
     9 x,y,w,h = cv2.boundingRect(contours[0])
    10 brcnt = np.array([[[x,y]] ,[[x+w , y]] , [[x+w , y+h]] , [[x,y+h]]] )
    11 cv2.drawContours(o , [brcnt] , -1 ,(255,255,255) , 2) 
    12 cv2.imshow("result" ,o)
    13 cv2.waitKey()
    14 cv2.destroyAllWindows()

    原图

    效果图

    2,使用函数cv2.boundingRect() 即cv2.rectangle()绘制矩形包围框

     1 import cv2                                                                       
     2 import numpy as np 
     3 o = cv2.imread("cc.bmp")
     4 gray = cv2.cvtColor(o , cv2.COLOR_BGR2GRAY)
     5 ret , binary = cv2.threshold(gray , 127 , 255 ,cv2.THRESH_BINARY)
     6 contours , hierarchy = cv2.findContours(binary , cv2.RETR_LIST ,
     7         cv2.CHAIN_APPROX_SIMPLE)
     8 x,y,w,h = cv2.boundingRect(contours[0])
     9 cv2.rectangle(o , (x,y) , (x+w , y+h) ,(255,255,255) , 2) 
    10 cv2.imshow("result" ,o)
    11 cv2.waitKey()
    12 cv2.destroyAllWindows()

    效果图

    3。,最小包围矩形框函数cv2.minAreaRect()

    该函数能绘制轮廓的最小包围矩形框,函数形式:

    retval = cv2.minAreaRect( points )

    返回值retval表示返回矩阵特征的信息,结构为(最小外接矩形的中心(x,y) , (宽度, 高度) , 旋转角度)

    points为轮廓

    返回值retval 结构不能用于函数cv2.drawContours() 参数结构要求, 需要将其转换为合适的参数结构,

    即使用函数cv2.boxPoints(box)

    import cv2                                                                       
    import numpy as np 
    o = cv2.imread("cc.bmp")
    cv2.imshow("original" , o) 
    gray = cv2.cvtColor(o , cv2.COLOR_BGR2GRAY)
    ret , binary = cv2.threshold(gray , 127, 255 , cv2.THRESH_BINARY)
    contours , hierarchy = cv2.findContours(binary , cv2.RETR_LIST ,  
            cv2.CHAIN_APPROX_SIMPLE)
    rect = cv2.minAreaRect(contours[0])
    print("rect:
    " , rect)
    points = cv2.boxPoints(rect)
    print("
    points_back:
    " , points)
    points = np.int0(points)
    binary = cv2.drawContours(o , [points] , 0 ,(255,255,255) , 2) 
    cv2.imshow("result" , o) 
    cv2.waitKey()
    cv2.destroyAllWindows()
    rect:
     ((280.3699951171875, 138.58999633789062), (154.99778747558594, 63.78103256225586), -8.130102157592773)
    
    points_back:
     [[208.16002  181.12    ]
     [199.14     117.979996]
     [352.57996   96.06    ]
     [361.59998  159.2     ]]

    rect表示返回的矩形特征信息

    points是一些点,时能够用作函数cv2.drawContours()参数的点

    4,最小包围圆形函数cv2.minEnclosingCircle()

    该函数构造一个对象的面积最小包围圆形,函数形式

    center , radius = cv2.minEnclosingCircle( points) 

    center为最小包围圆形的中心

    radius为最小包围圆形的半径

    points轮廓

     1 import cv2                                                                       
     2 o = cv2.imread("cc.bmp")
     3 cv2.imshow("original" , o) 
     4 gray = cv2.cvtColor(o , cv2.COLOR_BGR2GRAY)
     5 ret , binary = cv2.threshold(gray , 127 , 255 ,cv2.THRESH_BINARY)
     6 contours , hirrarchy = cv2.findContours( binary , cv2.RETR_LIST ,  
     7         cv2.CHAIN_APPROX_SIMPLE)
     8 (x,y) , radius = cv2.minEnclosingCircle(contours[0])
     9 center = (int(x) , int(y))
    10 radius = int(radius)
    11 cv2.circle(o , center , radius , (255,255,255) , 2) 
    12 cv2.imshow("resultl" , o) 
    13 cv2.waitKey()
    14 cv2.destroyAllWindows()

     5,最优拟合椭圆函数cv2.fitEllipse()

    可以构造最优拟合椭圆, 函数形式:

    retval = cv2.fitEllipse( points )

    retval 是RotatedRect()类型的值,这是因为该函数返回的是 拟合椭圆的外接矩形,包含外接矩形的质心,宽, 高,旋转角度

    ,正好与椭圆的中心点,轴长度,旋转角度等信息吻合

     1 import cv2                                                                       
     2 o = cv2.imread("cc.bmp")
     3 gray = cv2.cvtColor( o , cv2.COLOR_BGR2GRAY)
     4 ret , binary = cv2.threshold(gray , 127 , 255, cv2.THRESH_BINARY)
     5 contours , hierarchy = cv2.findContours(binary , cv2.RETR_LIST ,
     6         cv2.CHAIN_APPROX_SIMPLE)
     7 cv2.imshow("original" , o) 
     8 ellipse = cv2.fitEllipse(contours[0])
     9 print("ellipse=" , ellipse) 
    10 cv2.ellipse(o , ellipse ,(0 , 255, 0) , 3) 
    11 cv2.imshow("result" , o) 
    12 cv2.waitKey()
    13 cv2.destroyAllWindows()
                         

    6,最优拟合直线 函数cv2.fitLine()

    函数形式:  line = cv2.fitLine( points , distType , param , reps , aeps )

    line 返回的是最优拟合直线参数

    points是轮廓

    distType是距离类型,

    param是距离参数,与算选激励类型有关, 当参数设置为0时,会自动选择最优值

    reps表示拟合直线所需的径向精度,通常被设置为0.01

    aeps表示拟合直线所需的角度精度,通常被设置为0.01

    import cv2                                                                       
    o = cv2.imread("cc.bmp")
    cv2.imshow("original" , o) 
    gray = cv2.cvtColor(o , cv2.COLOR_BGR2GRAY)
    ret , binary = cv2.threshold(gray , 127 ,255 , cv2.THRESH_BINARY)
    contours , hierarchy = cv2.findContours(binary ,cv2.RETR_LIST ,  
            cv2.CHAIN_APPROX_SIMPLE)
    rows , cols = binary.shape[:2]
    [vx , vy , x, y] = cv2.fitLine(contours[0] , cv2.DIST_L2, 0,0.01 , 0.01)
    lefty = int((-x*vy/vx) + y) 
    righty = int(((cols - x) * vy/vx) + y )
    cv2.line(o , (cols -1 ,righty) , (0,lefty) , (0,255,0) , 2) 
    cv2.imshow("result" , o) 
    cv2.waitKey()
    cv2.destroyAllWindows()

    7,最优外包三角形函数 cv2.minEnclosingTriangle()

    retval , triangle = cv2.minEnclosingTreangle( points )

    retval 为最小外包三角形的面积

    triangle 最小外包三角形的三个顶点集

    points轮廓

     1 import cv2                                                                       
     2 o = cv2.imread("cc.bmp")
     3 cv2.imshow("original" , o) 
     4 gray = cv2.cvtColor(o , cv2.COLOR_BGR2GRAY)
     5 ret , binary = cv2.threshold(gray , 127 , 255 , cv2.THRESH_BINARY)
     6 contours , hierarchy = cv2.findContours(binary , cv2.RETR_LIST ,
     7         cv2.CHAIN_APPROX_SIMPLE)
     8 area , trgl = cv2.minEnclosingTriangle(contours[0])
     9 print("area = " , area)
    10 print("trgl:" , trgl)
    11 for i in range(0,3):
    12     cv2.line(o , tuple(trgl[i][0]), 
    13             tuple(trgl[(i+1) % 3][0]) , (255,255,255) , 2) 
    14 cv2.imshow("result" , o) 
    15 cv2.waitKey()
    16 cv2.destroyAllWindows()

    8,逼近多边形函数cv2.approxPolyDP()

    该函数用来构造指定精度的逼近多边形曲线,函数形式:

    approxCurve = cv2.approxPolyDP( curve , epsilon , closed)

    返回值approxCurve为逼近多边形的点集

    curve为轮廓

    epsilon为精度,原始轮廓的边界点与逼近多边形边界之间的最大值

    colsed为布尔值该值为True,毕竟多边形是封闭的,否则多边形不封闭

    该函数采用的是Douglas-Peucker算法,首先杂i轮廓上找到距离最远的两个点连接起来,然后在轮廓上找到离直线最远的点

    连接之前的点形成封闭的多边形,此时为三角形,按此方式不断的迭代将找到的离多边形最远的点加入,形成新的多边形

    当最远距离小于参数epsilon的值时,就停止迭代,该参数多设置为百分比形式

    import cv2
    o = cv2.imread("cc.bmp")
    cv2.imshow("original" , o)
    gray = cv2.cvtColor(o , cv2.COLOR_BGR2GRAY)
    ret , binary = cv2.threshold(gray , 127 , 255 ,cv2.THRESH_BINARY)
    contours , hierarchy = cv2.findContours(binary , cv2.RETR_LIST ,
            cv2.CHAIN_APPROX_SIMPLE)
    #epsilon = 0.1 * 周长
    adp = o.copy()
    epsilon = 0.1*cv2.arcLength(contours[0] , True)
    approx = cv2.approxPolyDP(contours[0] , epsilon , True)
    adp = cv2.drawContours(adp , [approx] , 0 ,( 0 , 0 ,255) , 2)
    cv2.imshow("result0.1" , adp)
    #epsilon = 0.09 * 周长
    adp = o.copy()
    epsilon = 0.09*cv2.arcLength(contours[0] , True)
    approx = cv2.approxPolyDP(contours[0] , epsilon , True)
    adp = cv2.drawContours(adp , [approx] , 0 ,( 0 , 0 ,255) , 2)
    cv2.imshow("result0.09" , adp)
    #epsilon = 0.055 * 周长
    adp = o.copy()
    epsilon = 0.055*cv2.arcLength(contours[0] , True)
    approx = cv2.approxPolyDP(contours[0] , epsilon , True)                          
    adp = cv2.drawContours(adp , [approx] , 0 ,( 0 , 0 ,255) , 2)
    cv2.imshow("result0.055" , adp)
    #epsilon = 0.05 * 周长
    adp = o.copy()
    epsilon = 0.05*cv2.arcLength(contours[0] , True)
    approx = cv2.approxPolyDP(contours[0] , epsilon , True)
    adp = cv2.drawContours(adp , [approx] , 0 ,( 0 , 0 ,255) , 2)
    cv2.imshow("result0.05" , adp)
    #epsilon = 0.02* 周长
    adp = o.copy()
    epsilon = 0.02*cv2.arcLength(contours[0] , True)
    approx = cv2.approxPolyDP(contours[0] , epsilon , True)
    adp = cv2.drawContours(adp , [approx] , 0 ,( 0 , 0 ,255) , 2)
    cv2.imshow("result0.02" , adp)
    #
    cv2.waitKey()
    cv2.destroyAllWindows()

    epsilon = 0.1 * 周长

    epsilon = 0.09 * 周长 

    epsilon = 0.055* 周长

     

    epsilon = 0.05 * 周长

     

    epsilon = 0.02 * 周长

     

  • 相关阅读:
    java基础-代理模式
    java基础-反射(细节)
    java基础-反射
    设计模式之单例
    23种设计模式汇总整理
    dialog--not attached to window manager
    java之设计模式
    android-sdk和api版本
    studio之mac快捷键
    控件之ReleLayout属性
  • 原文地址:https://www.cnblogs.com/miaorn/p/12264072.html
Copyright © 2011-2022 走看看