zoukankan      html  css  js  c++  java
  • Python OpenCV4获取轮廓最大内切圆和外接圆

    为了方便讲解,我们先来创建一个多边形做演示

    第一步:创建图像,并绘制一个六边形。代码和生成图像如下:

    # Create an image
    r = 100
    src = np.zeros((4*r, 4*r), dtype=np.uint8)
    
    # Create a sequence of points to make a contour
    vert = [None]*6
    vert[0] = (3*r//2, int(1.34*r))
    vert[1] = (1*r, 2*r)
    vert[2] = (3*r//2, int(2.866*r))
    vert[3] = (5*r//2, int(2.866*r))
    vert[4] = (3*r, 2*r)
    vert[5] = (5*r//2, int(1.34*r))
    # Draw it in src
    for i in range(6):
        cv.line(src, vert[i],  vert[(i+1)%6], ( 255 ), 3)
    
    cv.imshow("src", src)
    

    第二步:查找轮廓,计算图像上的点到轮廓的距离

    # Get the contours
    _, contours, _ = cv.findContours(src, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
    
    # Calculate the distances to the contour
    raw_dist = np.empty(src.shape, dtype=np.float32)
    for i in range(src.shape[0]):
        for j in range(src.shape[1]):
            raw_dist[i,j] = cv.pointPolygonTest(contours[1], (j,i), True)
    

    注意cv.RETR_TREE查找轮廓后轮廓是从外到内的排列顺序,那么contours[1]就是六边形的内边轮廓

    第三步:获取轮廓内部距离轮廓最远的点(作为内切圆圆心)和最小距离(作为内切圆半径),绘制内切圆

    # 获取最大值即内接圆半径,中心点坐标
    minVal, maxVal, _, maxDistPt = cv.minMaxLoc(raw_dist)
    minVal = abs(minVal)
    maxVal = abs(maxVal)
    
    result = cv.cvtColor(src,cv.COLOR_GRAY2BGR)
    
    cv.circle(result,maxDistPt, np.int(maxVal),(0,255,0), 2, cv.LINE_8, 0)
    cv.imshow('result', result) 

    最终效果:

     当然,如果你还想获取外接圆,直接调用函数cv2.minEnclosingCircle(即可),下面是代码演示和效果:

    # contours[0]对应最外层轮廓
    center,radius = cv.minEnclosingCircle(contours[0])
    cv.circle(result,(int(center[0]),int(center[1])),int(radius),(0,0,255),2)

    完整代码:

    import cv2 as cv
    import numpy as np
    
    # Create an image
    r = 100
    src = np.zeros((4*r, 4*r), dtype=np.uint8)
    
    # Create a sequence of points to make a contour
    vert = [None]*6
    vert[0] = (3*r//2, int(1.34*r))
    vert[1] = (1*r, 2*r)
    vert[2] = (3*r//2, int(2.866*r))
    vert[3] = (5*r//2, int(2.866*r))
    vert[4] = (3*r, 2*r)
    vert[5] = (5*r//2, int(1.34*r))
    # Draw it in src
    for i in range(6):
        cv.line(src, vert[i],  vert[(i+1)%6], ( 255 ), 3)
    
    cv.imshow("src", src)
    
    # Get the contours
    _, contours, _ = cv.findContours(src, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
    
    # Calculate the distances to the contour
    raw_dist = np.empty(src.shape, dtype=np.float32)
    for i in range(src.shape[0]):
        for j in range(src.shape[1]):
            raw_dist[i,j] = cv.pointPolygonTest(contours[1], (j,i), True)
    
    # 获取最大值即内接圆半径,中心点坐标
    minVal, maxVal, _, maxDistPt = cv.minMaxLoc(raw_dist)
    minVal = abs(minVal)
    maxVal = abs(maxVal)
    
    result = cv.cvtColor(src,cv.COLOR_GRAY2BGR)
    
    center,radius = cv.minEnclosingCircle(contours[0])
    cv.circle(result,(int(center[0]),int(center[1])),int(radius),(0,0,255),2)
    
    cv.circle(result,maxDistPt, np.int(maxVal),(0,255,0), 2, cv.LINE_8, 0)
    cv.imshow('result', result)
    
    cv.waitKey(0)
    cv.destroyAllWindows()

    关注【OpenCV与AI深度学习】获取更多学习资讯

    长按或者扫描下面二维码即可关注

  • 相关阅读:
    Firebase 如何创建登录 Token
    GitHub 如何从特定的版本中创建分支
    Firebase 命令行工具
    Python 日期格式和时间以及当前时间和时间戳
    Python DataTime 日期处理
    Python With 关键字和语句
    完整的微信接口类
    HashMap
    java运行时数据区域
    POI学习
  • 原文地址:https://www.cnblogs.com/stq054188/p/11882289.html
Copyright © 2011-2022 走看看