参考Matlab计算轮廓内切圆

初衷是为了求裂缝的最大宽度

直接上代码

import randomimport cv2
import math
import numpy as np
from numpy.ma import cos, sin
import matplotlib.pyplot as pltdef max_circle(f):img = cv2.imread(f, cv2.IMREAD_COLOR)img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# _, img_gray = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)contous, hierarchy = cv2.findContours(img_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)"""第二个参数表示轮廓的检索模式,有四种(本文介绍的都是新的cv2接口):cv2.RETR_EXTERNAL表示只检测外轮廓cv2.RETR_LIST检测的轮廓不建立等级关系cv2.RETR_CCOMP建立两个等级的轮廓,上面的一层为外边界,里面的一层为内孔的边界信息。如果内孔内还有一个连通物体,这个物体的边界也在顶层。cv2.RETR_TREE建立一个等级树结构的轮廓。第三个参数method为轮廓的近似办法cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法"""for c in contous:left_x = min(c[:, 0, 0])right_x = max(c[:, 0, 0])down_y = max(c[:, 0, 1])up_y = min(c[:, 0, 1])upper_r = min(right_x - left_x, down_y - up_y) / 2# 定义相切二分精度precision = math.sqrt((right_x - left_x) ** 2 + (down_y - up_y) ** 2) / (2 ** 13)# 构造包含轮廓的矩形的所有像素点Nx = 2 ** 8Ny = 2 ** 8pixel_X = np.linspace(left_x, right_x, Nx)pixel_Y = np.linspace(up_y, down_y, Ny)# [pixel_X, pixel_Y] = ndgrid(pixel_X, pixel_Y);# pixel_X = reshape(pixel_X, numel(pixel_X), 1);# pixel_Y = reshape(pixel_Y, numel(pixel_Y), 1);xx, yy = np.meshgrid(pixel_X, pixel_Y)# % 筛选出轮廓内所有像素点in_list = []for c in contous:for i in range(pixel_X.shape[0]):for j in range(pixel_X.shape[0]):if cv2.pointPolygonTest(c, (xx[i][j], yy[i][j]), False) > 0:in_list.append((xx[i][j], yy[i][j]))in_point = np.array(in_list)pixel_X = in_point[:, 0]pixel_Y = in_point[:, 1]# 随机搜索百分之一像素提高内切圆半径下限N = len(in_point)rand_index = random.sample(range(N), N // 100)rand_index.sort()radius = 0big_r = upper_rcenter = Nonefor id in rand_index:tr = iterated_optimal_incircle_radius_get(c, in_point[id][0], in_point[id][1], radius, big_r, precision)if tr > radius:radius = trcenter = (in_point[id][0], in_point[id][1]) # 只有半径变大才允许位置变更,否则保持之前位置不变# 循环搜索剩余像素对应内切圆半径loops_index = [i for i in range(N) if i not in rand_index]for id in loops_index:tr = iterated_optimal_incircle_radius_get(c, in_point[id][0], in_point[id][1], radius, big_r, precision)if tr > radius:radius = trcenter = (in_point[id][0], in_point[id][1])    # 只有半径变大才允许位置变更,否则保持之前位置不变# 效果测试plot_x = np.linspace(0, 2 * math.pi, 100)circle_X = center[0] + radius * cos(plot_x)circle_Y = center[1] + radius * sin(plot_x)print(radius * 2)plt.figure()plt.imshow(img_gray)plt.plot(circle_X, circle_Y)plt.show()def iterated_optimal_incircle_radius_get(contous, pixelx, pixely, small_r, big_r, precision):radius = small_rL = np.linspace(0, 2 * math.pi, 360)  # 确定圆散点剖分数360, 720circle_X = pixelx + radius * cos(L)circle_Y = pixely + radius * sin(L)for i in range(len(circle_Y)):if cv2.pointPolygonTest(contous, (circle_X[i], circle_Y[i]), False) < 0:    # 如果圆散集有在轮廓之外的点return 0while big_r - small_r >= precision:   # 二分法寻找最大半径half_r = (small_r + big_r) / 2circle_X = pixelx + half_r * cos(L)circle_Y = pixely + half_r * sin(L)if_out = Falsefor i in range(len(circle_Y)):if cv2.pointPolygonTest(contous, (circle_X[i], circle_Y[i]), False) < 0:  # 如果圆散集有在轮廓之外的点big_r = half_rif_out = Trueif not if_out:small_r = half_rradius = small_rreturn radiusif __name__ == '__main__':max_circle('thresh_crack.png')

Python实现任意多边形的最大内切圆算法相关推荐

  1. python计算任意多边形面积

    看了一些方法网上的资料,也自己倒腾了一些想法. 然后看到这个大神的博客(<计算任意多边形的面积>),我就服气了. 我把代码转换为python: # 计算任意多边形的面积,顶点按照顺时针或者 ...

  2. python画正方形内切圆_任意多边形最大内接圆算法的Python实现,内切圆

    初衷是为了求裂缝的最大宽度 直接上代码 import random import cv2 import math import numpy as np from numpy.ma import cos ...

  3. python 画任意多边形

    urtle是Python内置的图形库,在这里,我们需要知道正多边形内角计算公式:内角=(边数-2)*180/边数 可选项:提示输入一种颜色,进行填充. 本程序运行环境是Python3的IDLE. '' ...

  4. python计算多边形的面积并保留两位小数_计算任意多边形面积的Python实现

    最近需要实现一个计算非凸多边形面积的功能,需要输入是顺次排序的多边形顶点坐标,假设输入的多边形顶点是V={v0, v1, v2, -, vn-1},则多边形的边为E={, , ,...,, }.要求输 ...

  5. 计算任意多边形面积的Python实现

    最近需要实现一个计算非凸多边形面积的功能,需要输入是顺次排序的多边形顶点坐标,假设输入的多边形顶点是V={v0, v1, v2, -, vn-1},则多边形的边为E={<v0, v1>, ...

  6. 求任意多边形内部水平方向似最大矩形算法实现

    背景说明 前段时间有个求点是否在多边形内部的需求,折腾了不少时间,现截取其中的的重点部分--求任意多边形内部水平方向似最大矩形--来搞篇博客. 求点是否在多边形内部这个算法很容易搞,一搜一大把,但数据 ...

  7. python画椭圆-python opencv圆、椭圆与任意多边形的绘制实例详解

    圆形的绘制 : OpenCV中使用circle(img,center,radius,color,thickness=None,lineType=None,shift=None)函数来绘制圆形 impo ...

  8. 一种求任意多边形内部水平方向似最大矩形的算法

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 在前一篇中,我们探讨了如何求凸多边形中的似最大圆,但是针对实际 ...

  9. Python 3.X 用Thinker做任意多边形的缩放图(一)

    Python 3.X 用Thinker做任意多边形的缩放图(需要根据实际图形做修改) 功能介绍一 引用库 thinker import tkinter as tk 功能介绍二 模块初始化 root = ...

最新文章

  1. 3、构建bass服务及model
  2. 类型上限_类型或可成为影视市场下一红利点__枫筹网
  3. jooq_jOOQ API设计缺陷的怪异事件
  4. [转载]设计模式解密(23) - 总结篇
  5. vc6开发一个抓包软件_开发一个软件要多少钱?app软件开发的费用
  6. vue 运行报错Module build failed: Error: Node Sass does not yet support your current environment: Windows
  7. 第一章 Windows编程基础(1~4课)
  8. case when then else_SQL 优化大神玩转 MySQL函数系列_case_when 的坑
  9. HDOJ 4223 (DP)
  10. 命令行配置Windows SNMP服务
  11. 阶段5 3.微服务项目【学成在线】_day03 CMS页面管理开发_07-新增页面-前端-页面完善...
  12. 顶级赛事!2021 CCF大数据与计算智能大赛强势来袭~
  13. Qt创建桌面快捷方式
  14. Python显示WiFi密码
  15. 最大值最小值计算机一级,Excel2019中突出数据最大值和最小值的方法详解
  16. 号外 ! 号外 ! V7包下的View都来此参加同学会 , 快来看,快来看...
  17. 通过PS把普通数码照片制作成素描照片
  18. 电阻为何是标准的及各精度的标准阻值表
  19. IntelliJ IDEA--配置导入导出
  20. TI Sitara系列AM64x核心板(双核ARM Cortex-A53)软硬件规格资料

热门文章

  1. 计算机的端口以及tcp/ip中的端口
  2. Linux Rootkit的反侦测手段漫谈
  3. linux u盘版下载官网,Linux助手:Universal USB Installer新版下载
  4. 灵魂站队:结婚,男的压力大,还是女的压力大?
  5. 树莓派3B安装64位操作系统(树莓派无需连接显示器键盘鼠标)
  6. 2008Noip解题报告
  7. VS2008下编写Colors应用程序
  8. TOM 163VIP邮箱怎么登录?163.net邮箱登录界面是什么?
  9. java presentation
  10. 石川圖 / 鱼骨图 / 關鍵要因圖 / 因果圖