美文网首页
图像轮廓(1)

图像轮廓(1)

作者: Tsukinousag | 来源:发表于2021-10-26 21:23 被阅读0次

    边缘检测虽然能够检测出边缘,但是边缘不是连续的,检测到的边缘不是一个整体。图像轮廓是指将边缘连接起来形成一个整体

    #查找图像轮廓
    cv2.findContours()
    
    #绘制轮廓图像
    cv2.drawContours()
    

    查找图像轮廓

    image,contours,hierarchy=cv2.findContours(image,mode,method)
    
    • image:前后两个image一致,灰度图像会被自动处理为二值图像

    • contours:轮廓组,每个轮廓由若干个点构成,且contours[i]表示第i个轮廓,contours[i][j]表示第i个轮廓的第j个点,contours的type是list,list的每个元素都是图像的一个轮廓,是Numpy的ndarray结构

    print(contours[0])
    [[[79 270]]
     [[79 383]]
     [[195 383]]
     [[195 270]]]
    
    • hierarchy:返回父子轮廓的层次关系,mode决定其参数
    [Next , Previous , First_Child , Parent]
    [后一个轮廓的索引编号,前一个轮廓的索引编号,第一个子轮廓的索引编号,父轮廓的索引编号]
    上述参数没有对应关系时,设置为" -1 "
    
    • mode:轮廓检索模式

    cv2.RETR_LIST:对检测到的轮廓不建立等级关系

    cv2.RETR_EXTERNAL:只检测外轮廓

    cv2.RETE_CCOMP:检测所有轮廓并组织成两级层次结构,上面一层为外边界,下面一层为内控的边界
    (注:当含有多个层次结构时,其也只会得到两层的层次结构,而TREE会得到多层)

    cv2.RETR_TREE:建立一个等级树结构的轮廓

    • method:轮廓近似方法

    如何表达轮廓

    cv2.CHAIN_APPROX_SIMPLE:压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点元素

    cv2.CHAIN_APPROX_NONE:存储所有轮廓点

    注意点:

    • image必须是灰度二值图像
    • 在opencv中都是从黑色背景中查找白色对象,因此对象必须是白色,背景必须是黑色
    • opencv 4.x中,第一个返回的image忽略,只有两个返回值

    绘制图像轮廓

    image=cv2.drawContours(image,contours,contourIdx,RGB,画笔粗细,...)
    

    返回值image:绘制了轮廓的图像
    参数:
    image:待绘制轮廓的图像,会在image上直接绘制,后续如果image原始图像有用,需要先复制备份
    contours:需要绘制的轮廓
    contourIdx:一个整数或者0,表示对应的索引号;-1表示绘制全部轮廓

    thickness:-1,表示绘制实心轮廓


    绘制一副图像中的所有轮廓

    import cv2
    
    img=cv2.imread('D:/part12/part12_2.bmp')
    cv2.imshow("img",img)
    
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    
    ret,binary=cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
    
    contours,hierarchy=cv2.findContours(binary,
                                              cv2.RETR_EXTERNAL,
                                              cv2.CHAIN_APPROX_SIMPLE)
    
    img=cv2.drawContours(img,contours,-1,(0,0,255),5)
    
    cv2.imshow("img",img)
    cv2.waitKey(0)
    cv2.destroyWindow()
    

    逐个显示一幅图像中的边缘信息

    import cv2
    import numpy as np
    
    img=cv2.imread("D:/part12/part12_2.bmp")
    
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    ret,binary=cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
    contours,hierarchy=cv2.findContours(binary,
                                        cv2.RETR_EXTERNAL,
                                        cv2.CHAIN_APPROX_SIMPLE)
    
    n=len(contours)
    contoursImg=[]
    for i in range(n):
        temp=np.zeros(img.shape,np.uint8)
        contoursImg.append(temp)
        contoursImg[i]=cv2.drawContours(contoursImg[i],contours,i,(255,255,255),5)
        cv2.imshow("contours["+str(i)+"]",contoursImg[i])
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    使用轮廓绘制功能,提取前景图像

    import cv2
    import numpy as np
    
    img=cv2.imread("D:/hjbzwy.jpg")
    
    gray=cv2.cvtColor(img,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)
    
    mask=np.ones(img.shape,np.uint8)
    mask=cv2.drawContours(mask,contours,-1,(255,255,255),-1)
    
    cv2.imshow("mask",mask)
    
    loc=cv2.bitwise_and(img,mask)
    
    cv2.imshow("loc",loc)
    
    cv2.waitKey(0)
    cv2.destroyWindow()
    

    矩特征

    比较两个轮廓最简单的方法是比较二者的轮廓矩。轮廓矩代表了一个轮廓,一幅图像,一组点集的全部特征,矩信息包含了对应对象的不同类型的几何特征,例如大小,位置,角度,形状等。如果两个轮廓的矩一致,那么这两个轮廓就是一致的。

    矩特征被广泛应用在模式识别图像识别方面

    retval=cv2.moments(array,binaryImage)
    

    空间矩(m00表示轮廓的面积)
    中心矩(比较不同位置上两个对象的一致性)
    归一化中心矩(不仅具有平移不变性,还具有缩放不变性)

    array:可以是点集,灰度图像,二值图像
    binaryImage:该参数为True时,arry内所有的非零值被处理为1,也就是二值化仅在array为图像时有效


    由m00观察每个轮廓的面积
    import cv2
    import numpy as np
    
    img=cv2.imread("D:/part12/part12_4.bmp")
    
    cv2.imshow("img",img)
    
    gray=cv2.cvtColor(img,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)
    
    n=len(contours)
    contourImg=[]
    
    for i in range(n):
        temp=np.zeros(img.shape,np.uint8)
        contourImg.append(temp)
        contourImg[i]=cv2.drawContours(contourImg[i],contours,i,255,3)
    
    for i in range(n):
        print(cv2.moments(contours[i]))
        print(cv2.moments(contours[i])['m00'])
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    {'m00': 13764.0, 'm10': 1348872.0, 'm01': 4081026.0, 'm20': 149825728.0, 'm11': 399940548.0, 'm02': 1224156396.0, 'm30': 18139630656.0, 'm21': 44423328352.0, 'm12': 119967326808.0, 'm03': 371342758305.0, 'mu20': 17636272.0, 'mu11': 0.0, 'mu02': 14132187.0, 'mu30': 0.0, 'mu21': 0.0, 'mu12': 0.0, 'mu03': 0.0, 'nu20': 0.09309309309309309, 'nu11': 0.0, 'nu02': 0.07459677419354839, 'nu30': 0.0, 'nu21': 0.0, 'nu12': 0.0, 'nu03': 0.0}
    13764.0
    {'m00': 30381.0, 'm10': 8582632.5, 'm01': 4055863.5, 'm20': 2579053217.0, 'm11': 1145781438.75, 'm02': 579760623.0, 'm30': 815852171501.25, 'm21': 344303604469.5, 'm12': 163782375997.5, 'm03': 87624902985.75, 'mu20': 154459535.75, 'mu11': 0.0, 'mu02': 38302845.75, 'mu30': 0.0, 'mu21': 0.0, 'mu12': 0.0, 'mu03': 0.0, 'nu20': 0.16734417344173438, 'nu11': 0.0, 'nu02': 0.04149797570850201, 'nu30': 0.0, 'nu21': 0.0, 'nu12': 0.0, 'nu03': 0.0}
    30381.0
    {'m00': 3348.0, 'm10': 1638846.0, 'm01': 117180.0, 'm20': 804628188.0, 'm11': 57359610.0, 'm02': 4462884.0, 'm30': 396227894535.0, 'm21': 28161986580.0, 'm12': 2184581718.0, 'm03': 181511820.0, 'mu20': 2413071.000000119, 'mu11': 0.0, 'mu02': 361584.0, 'mu30': -6.103515625e-05, 'mu21': 3.4570693969726562e-06, 'mu12': 2.9802322387695312e-08, 'mu03': 0.0, 'nu20': 0.2152777777777884, 'nu11': 0.0, 'nu02': 0.03225806451612903, 'nu30': -9.410581005043431e-14, 'nu21': 5.330211897387881e-15, 'nu12': 4.595010256368863e-17, 'nu03': 0.0}
    3348.0
    

    计算轮廓的面积

    retval=cv2.contourArea(contour,oriented)
    

    oriented:
    True,返回值包含正负号,用来表示轮廓是顺时针还是逆时针
    False,表示返回的retval是一个绝对值

    计算轮廓的长度

    retval=cv2.arcLength(curve,closed)
    

    closed:
    True,轮廓封闭
    False,轮廓不封闭


    轮廓面积实验

    import cv2
    import numpy as np
    
    img=cv2.imread("D:/part12/part12_2.bmp")
    
    gray=cv2.cvtColor(img,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)
    
    n=len(contours)
    contoursImg=[]
    for i in range(n):
        print("contours["+str(i)+"]面积=",cv2.contourArea(contours[i]))
        temp=np.zeros(img.shape,np.uint8)
        contoursImg.append(temp)
        contoursImg[i]=cv2.drawContours(contoursImg[i],contours,i,(255,255,255),3)
        cv2.imshow("contours["+str(i)+"]",contoursImg[i])
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    contours[0]面积= 11220.0
    contours[1]面积= 11035.5
    contours[2]面积= 10126.0
    

    轮廓长度实验

    import cv2
    import numpy as np
    
    img=cv2.imread("D:/part12/part12_5.bmp")
    
    gray=cv2.cvtColor(img,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)
    n=len(contours)
    cntlen=[]
    for i in range(n):
        cntlen.append(cv2.arcLength(contours[i],True))
        print("第"+str(i)+"个轮廓的长度是:%d" % cntlen[i])
    
    cntlensum=np.sum(cntlen)
    cntlenavg=cntlensum/n
    
    print("轮廓的总长度是:%d" % cntlensum)
    print("轮廓的平均长度是:%d" % cntlenavg)
    
    #显示超过平均值的轮廓
    contourImg=[]
    for i in range(n):
        temp=np.zeros(img.shape,np.uint8)
        contourImg.append(temp)
        contourImg[i]=cv2.drawContours(contourImg[i],contours,i,(255,255,255),3)
        if cv2.arcLength(contours[i],True)>cntlenavg:
            cv2.imshow("contours["+str(i)+"]",contourImg[i])
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    第0个轮廓的长度是:205
    第1个轮廓的长度是:199
    第2个轮廓的长度是:700
    第3个轮廓的长度是:881
    第4个轮廓的长度是:1106
    第5个轮廓的长度是:546
    第6个轮廓的长度是:787
    第7个轮廓的长度是:956
    轮廓的总长度是:5382
    轮廓的平均长度是:672
    

    Hu矩

    Hu矩是归一化中心矩的线性组合。Hu矩在图像旋转,平移,缩放等操作后,仍能保持矩的不变性,所以经常拿Hu矩作为识别图像的特征

    hu=cv2.HuMoments(m)
    

    其中,hu是表示返回的Hu矩值,m是由参数cv2.moments()计算得到的矩特征值

    import cv2
    img1=cv2.imread("D:/part12/part12_6.bmp")
    img2=cv2.imread("D:/part12/part12_9.bmp")
    img3=cv2.imread("D:/part12/part12_7.bmp")
    
    gray1=cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
    gray2=cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
    gray3=cv2.cvtColor(img3,cv2.COLOR_BGR2GRAY)
    
    hum1=cv2.HuMoments(cv2.moments(gray1)).flatten()
    hum2=cv2.HuMoments(cv2.moments(gray2)).flatten()
    hum3=cv2.HuMoments(cv2.moments(gray3)).flatten()
    
    print("hum1-hum2 = " ,hum1-hum2)
    print("hum2-hum3 = " ,hum2-hum3)
    print("hum1-hum2 = " ,hum1-hum3)
    

    由于Hu矩的值本身就非常的小,因此这里没有发现两个对象的Hu矩差值的特殊意义

    hum1-hum2 =  [ 1.10252089e-04  1.58852755e-07 -1.06979452e-11  1.70011798e-12
      3.94358178e-23  1.31166167e-15 -1.46520812e-23]
    hum2-hum3 =  [-2.31106854e-04 -4.04824074e-07 -1.72068592e-10 -4.52145391e-11
     -3.85337150e-21 -1.80608902e-14 -2.58397648e-21]
    hum1-hum2 =  [-1.20854765e-04 -2.45971319e-07 -1.82766537e-10 -4.35144211e-11
     -3.81393569e-21 -1.67492286e-14 -2.59862856e-21]
    

    形状匹配

    通过Hu矩来判断两个对象的一致性

    retval=cv2.matchShapes(contour1,contour2,cv2.CONTOURS_MATCH_I1,0)
    
    import cv2
    
    img1=cv2.imread("D:/part12/part12_7.bmp")
    img2=cv2.imread("D:/part12/part12_9.bmp")
    img3=cv2.imread("D:/part12/part12_1.bmp")
    
    gray1=cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
    gray2=cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
    gray3=cv2.cvtColor(img3,cv2.COLOR_BGR2GRAY)
    
    ret1,binary1=cv2.threshold(gray1,127,255,cv2.THRESH_BINARY)
    ret2,binary2=cv2.threshold(gray2,127,255,cv2.THRESH_BINARY)
    ret3,binary3=cv2.threshold(gray3,127,255,cv2.THRESH_BINARY)
    
    contours1,hierarchy1=cv2.findContours(binary1,
                                          cv2.RETR_LIST,
                                          cv2.CHAIN_APPROX_SIMPLE)
    
    contours2,hierarchy2=cv2.findContours(binary2,
                                          cv2.RETR_LIST,
                                          cv2.CHAIN_APPROX_SIMPLE)
    
    contours3,hierarchy3=cv2.findContours(binary3,
                                          cv2.RETR_LIST,
                                          cv2.CHAIN_APPROX_SIMPLE)
    
    cnt1=contours1[0]
    cnt2=contours2[0]
    cnt3=contours3[0]
    
    ret0=cv2.matchShapes(cnt1,cnt1,1,0.0)
    ret1=cv2.matchShapes(cnt1,cnt2,1,0.0)
    ret2=cv2.matchShapes(cnt1,cnt3,1,0.0)
    
    print("相同图像的matchShapes=",ret0)
    print("相似的图像的matchShapes=",ret1)
    print("不同图像的matchShapes=",ret2)
    
    相同图像的matchShapes= 0.0
    相似的图像的matchShapes= 0.6671988353714976
    不同图像的matchShapes= 0.8752263821862232
    

    轮廓拟合

    1. 矩形包围框

    retval=cv2.boundingRect(轮廓/灰度图)
    

    其中 retval返回左上角顶点的x,y以及宽和高(x,y,w,h)

    import cv2
    import numpy as np
    
    img=cv2.imread("D:/part12/part12_1.bmp")
    
    gray=cv2.cvtColor(img,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)
    
    x,y,w,h=cv2.boundingRect(contours[0])
    
    brcnt=np.array([[[x,y]],[[x+w,y]],[[x+w,y+h]],[[x,y+h]]])
    
    #注意画笔的顺序方向
    
    img=cv2.drawContours(img,[brcnt],-1,(255,255,255),2)
    
    cv2.imshow("img",img)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    采用cv2.boundingRect()和cv2.rectangle()绘制矩形包围框

    import cv2
    
    img=cv2.imread("D:/part12/part12_1.bmp")
    
    gray=cv2.cvtColor(img,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)
    
    x,y,w,h=cv2.boundingRect(contours[0])
    cv2.rectangle(img,(x,y),(x+w,y+h),(255,255,255),2)
    
    cv2.imshow('img',img)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    2. 最小包围矩形框

    box = cv2.minAreaRect(points)
    

    此处返回的[最小外接矩形中心,(宽,高),旋转角度],必须经过下面函数

    points = cv2.boxPoints(box)
    

    此处的points值再经过np.int0()取整,可以应用于cv2.drawContours()

    import cv2
    import numpy as np
    
    img=cv2.imread("D:/part12/part12_1.bmp")
    
    gray=cv2.cvtColor(img,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)
    
    points=cv2.minAreaRect(contours[0])
    points=cv2.boxPoints(points)
    points=np.int0(points)
    
    image=cv2.drawContours(img,[points],0,(255,255,255),2)
    
    cv2.imshow("image",image)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    3. 最小包围圆形

    center,radius=cv2.minEnclosingCircle(points)
    
    import cv2
    import numpy as np
    
    img=cv2.imread("D:/part12/part12_1.bmp")
    
    gray=cv2.cvtColor(img,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)
    
    (x,y),radius=cv2.minEnclosingCircle(contours[0])
    center=(int(x),int(y))
    radius=int(radius)
    
    cv2.circle(img,center,radius,(255,255,255),2)
    
    cv2.imshow("image",img)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    4. 最优拟合椭圆

    retval=cv2.fitEllipse(points)
    
    import cv2
    import numpy as np
    
    img=cv2.imread("D:/part12/part12_1.bmp")
    
    gray=cv2.cvtColor(img,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)
    ellipse=cv2.fitEllipse(contours[0])
    
    cv2.ellipse(img,ellipse,(0,255,0),3)
    
    cv2.imshow("image",img)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    5. 最优拟合直线

    cv2.fitLine(points,distType,0,0.01,0.01)
    
    import cv2
    import numpy as np
    
    img=cv2.imread("D:/part12/part12_1.bmp")
    
    gray=cv2.cvtColor(img,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=img.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(img,(cols-1,righty),(0,lefty),(0,255,0),2)
    cv2.imshow("image",img)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    6. 最小外包三角形

    retval,triangle=cv2.minEnclosingTraingle(points)
    

    retval:最小外包三角形的面积
    triangle:最小外包三角形的三个顶点集

    注意:三个顶点集的坐标必须转化为整数

    import cv2
    import numpy as np
    
    img=cv2.imread("D:/part12/part12_1.bmp")
    
    gray=cv2.cvtColor(img,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)
    
    area,trgl=cv2.minEnclosingTriangle(contours[0])
    print("area:",area)
    print("trgl",trgl)
    for i in range(0,3):
        cv2.line(img,tuple(np.int0(trgl[i][0])),tuple(np.int0(trgl[(i+1)%3][0])),(255,255,255),2)
    
    cv2.imshow("result",img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    7. 逼近多边形

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

    返回值:逼近多边形的点集
    参数:轮廓,原始轮廓边界点与逼近多边形边界之间的最大距离,True:封闭;False不封闭

    DP算法:该算法首先从轮廓中找到距离最远的两个点,并且将两点相连。接下来在轮廓上找到一个距离当前直线最远的点,并且将该点与原有直线连成一个封闭多边形,上述过程不断迭代,将新的找到的距离当前多边形最远的点加入到结果中。当轮廓上所有的点到当前多边形的距离都小于函数cv2.approxPolyDP()的参数epsilon的值时,就停止迭代

    构造不同精度的逼近多边形

    import cv2
    
    img=cv2.imread("D:/part12/part12_1.bmp")
    
    cv2.imshow("img",img)
    
    gray=cv2.cvtColor(img,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)
    
    #------------------------------0.1周长
    adp=img.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("result 0.1",adp)
    
    #-------------------------------0.09周长
    adp=img.copy()
    epsilon=0.09*cv2.arcLength(contours[0],True)
    approx=cv2.approxPolyDP(contours[0],epsilon,True)
    cv2.drawContours(adp,[approx],0,(0,0,255),2)
    cv2.imshow("result 0.09",adp)
    
    #--------------------------------0.055周长
    adp=img.copy()
    epsilon=0.055*cv2.arcLength(contours[0],True)
    approx=cv2.approxPolyDP(contours[0],epsilon,True)
    cv2.drawContours(adp,[approx],0,(0,0,255),2)
    cv2.imshow("result 0.055",adp)
    
    #---------------------------------0.02周长
    adp=img.copy()
    epsilon=0.02*cv2.arcLength(contours[0],True)
    approx=cv2.approxPolyDP(contours[0],epsilon,True)
    cv2.drawContours(adp,[approx],0,(0,0,255),2)
    cv2.imshow("result 0.02",adp)
    
    cv2.waitKey()
    cv2.destroyAllWindows()
    

    相关文章

      网友评论

          本文标题:图像轮廓(1)

          本文链接:https://www.haomeiwen.com/subject/vniealtx.html