多边形(轮廓点)等距离外扩

1.需要安装一个python包

安装 pyclipper python 的话,直接pip install pyclipper
地址:https://pypi.org/project/pyclipper/
中文文档:https://www.cnblogs.com/zhigu/p/11943118.html

2.轮廓点等距离外扩

def equidistant_zoom_contour(contour, margin):"""等距离缩放多边形轮廓点:param contour: 一个图形的轮廓格式[[[x1, x2]],...],shape是(-1, 1, 2):param margin: 轮廓外扩的像素距离,margin正数是外扩,负数是缩小:return: 外扩后的轮廓点"""pco = pyclipper.PyclipperOffset()##### 参数限制,默认成2这里设置大一些,主要是用于多边形的尖角是否用圆角代替pco.MiterLimit = 10contour = contour[:, 0, :]pco.AddPath(contour, pyclipper.JT_MITER, pyclipper.ET_CLOSEDPOLYGON)solution = pco.Execute(margin)solution = np.array(solution).reshape(-1, 1, 2).astype(int)return solution

调用示例子:

import pyclipper
import math
from shapely.geometry import LineString, Polygon, MultiLineString, Point, MultiPointpoly = np.array([[[200, 200]], [[200, 300]], [[400, 350]], [[350, 200]], [[300, 200]], [[200, 100]]])
contour1 = equidistant_zoom_contour(poly, 20)
img = np.zeros((500, 500, 3))
cv2.polylines(img, [poly], True, (0, 0, 255), 3)
cv2.polylines(img, [contour1], True, (0, 255, 0), 3)

结果展示:

3.轮廓点等比例缩放

def perimeter(poly):p = 0nums = poly.shape[0]for i in range(nums):p += abs(np.linalg.norm(poly[i % nums] - poly[(i + 1) % nums]))return pdef proportional_zoom_contour(contour, ratio):"""多边形轮廓点按照比例进行缩放:param contour: 一个图形的轮廓格式[[[x1, x2]],...],shape是(-1, 1, 2):param ratio: 缩放的比例,如果大于1是放大小于1是缩小:return:"""poly = contour[:, 0, :]area_poly = abs(pyclipper.Area(poly))perimeter_poly = perimeter(poly)poly_s = []pco = pyclipper.PyclipperOffset()pco.MiterLimit = 10if perimeter_poly:d = area_poly * (1 - ratio * ratio) / perimeter_polypco.AddPath(poly, pyclipper.JT_MITER, pyclipper.ET_CLOSEDPOLYGON)poly_s = pco.Execute(-d)poly_s = np.array(poly_s).reshape(-1, 1, 2).astype(int)return poly_s

调用示范:

import pyclipper
import math
from shapely.geometry import LineString, Polygon, MultiLineString, Point, MultiPoint
poly = np.array([[[200, 200]], [[200, 300]], [[400, 350]], [[350, 200]], [[300, 200]], [[200, 100]]])
contour1 = proportional_zoom_contour(poly, 1.5)
img = np.zeros((500, 500, 3))
cv2.polylines(img, [contour1], True, (0, 255, 0), 3)
cv2.polylines(img, [poly], True, (0, 0, 255), 3)

其中 pco.MiterLimit = 10这个参数默认是2,如果是默认的值结果图第一个,改成10的话,结果图就是第二个,是一个尖角的区别

4.图形轮廓点的旋转

# 获取一个形状的质心
def get_centroid(coord):coord = np.array(coord)shape = coord.shapeif len(shape) == 1 and len(coord) == 2:  # pointreturn coordif len(shape) == 1 and len(coord) == 4:  # bounding boxreturn tuple([(coord[0] + coord[2]) // 2, (coord[1] + coord[3]) // 2])elif len(shape) == 2 and shape[-1] == 2:if shape[0] == 2:  # 如果是直线cen = LineString(coord).centroidelse:cen = Polygon(coord).centroidreturn tuple(map(int, [cen.x, cen.y]))elif len(shape) == 3 and shape[1:] == (1, 2):  # contourcen = Polygon(coord.squeeze()).centroidreturn tuple(map(int, [cen.x, cen.y]))else:raise Exception('coordinate error, must be bbox or contour shape:{}'.format(coord))def point_Srotate(im_w, im_h, angle, spin_point, origin_point):""":param im_w: 原始点所在的图片的宽度:param im_h: 原始点所在的图片的高度:param angle: 旋转的角度:param spin_point: 旋转的点:param origin_point: 参考点:return: 旋转过后的点"""row, col = im_h, im_w# P(x1, y1),绕某个像素点Q(x2, y2)x1, y1 = spin_pointx2, y2 = origin_pointy1 = row - y1y2 = row - y2x = (x1 - x2) * math.cos(math.pi / 180.0 * angle) - (y1 - y2) * math.sin(math.pi / 180.0 * angle) + x2y = (x1 - x2) * math.sin(math.pi / 180.0 * angle) + (y1 - y2) * math.cos(math.pi / 180.0 * angle) + y2x = xy = row - yreturn [x, y]

调用示范

import pyclipper
import math
from shapely.geometry import LineString, Polygon, MultiLineString, Point, MultiPoint
# 以多边形轮廓的质心为参照点进行旋转
poly = np.array([[[200, 200]], [[200, 300]], [[400, 350]], [[350, 200]], [[300, 200]], [[200, 100]]])origin_point = get_centroid(poly)
spin_list = []
for con in poly:print('con', con)new = point_Srotate(500, 500, 50, con[0], origin_point)spin_list.append(new)
spin_con = np.array(spin_list).reshape(-1, 1, 2).astype(int)
img = np.zeros((500, 500, 3))
cv2.polylines(img, [spin_con], True, (0, 255, 0), 3)
cv2.polylines(img, [poly], True, (0, 0, 255), 3)

结果图:

5.其他外扩的函数

def extend_contour2(contour, margin):# 每个点相对于质心进行外扩一定的距离""":param contour: 轮廓点集合:param margin: 外扩的距离:return: 外扩后的轮廓点集"""#### 求该轮廓的质心 ####gravity_point = get_centroid(contour)#### 获取最左下的点 ##### min_x = np.minimum(contour)#### 计算所有的轮廓点与质心所组成的向量,计算向量的模vector_arr = contour - np.array(gravity_point)vector_length = np.linalg.norm(vector_arr, axis=2)#### 计算所有的点针对对外扩的像素需要放大多少倍ratio = 1 + margin / vector_lengthratio = np.concatenate([ratio, ratio], axis=1)#### 进行坐标的缩放contour_ext = (vector_arr[:, 0, :] * ratio + np.array(gravity_point)).reshape(-1, 1, 2)contour_ext = contour_ext.astype(int)return contour_extdef coordinate_conversion(reference_point, contour, ratio):# 对凸多边形有用,对凹多边形容易变形,成比例缩放轮廓""":param reference_point: 参照点的坐标:param contour: 图像的轮廓点:param ratio: 缩放的比例:return: 以参照点不变将轮廓点获取缩放后的轮廓点坐标"""contour_trans_array = (contour - np.array(reference_point)) * ratio + np.array(reference_point)contour_trans_array = contour_trans_array.astype(int)return contour_trans_array

多边形轮廓 等距离外扩相关推荐

  1. 多边形或轮廓等距离外扩或收缩

    参考:多边形或轮廓等距离外扩或收缩_hjk61314的博客-CSDN博客_多边形外扩 1. 需求 已知:给定一个简单多边形,多边形按照顺时针或者逆时针的数组排列, 求:内部等距离缩小或者外部放大的多边 ...

  2. opencv 实现多边形内缩/外扩(平移)指定距离

    实现多边形内缩,内缩以后的每边仍与内缩前平行. Note: 确保函数种pList的点按逆时针顺序排列好! 此外,使用Point2f类型可以获得亚像素精度. 功能函数: /* @作用:多边形内缩 @pL ...

  3. 图形/多段线内缩外扩思路

    图形/多段线内缩外扩思路 前言 我在网上找了很多关于多边形内缩外扩的资料,也测试了一些算法库,如Clipper,boost::geometry::buffer,其实都可以得到不错的结果. Clippe ...

  4. JAVA实现小精度多边形等距外扩

    涉及技术 腾讯地图 jdk1.8 问题描述 开发一款应用,前端在地图上标记经纬度坐标点集合形成一个多边形,现需要在后端将多边形做一个等距外扩或者收缩. 在网上查了好多的算法,经过尝试验证,在小经度多边 ...

  5. 多边形轮廓等比例缩放

    多边形(轮廓点)等距离外扩 1.需要安装一个python包 安装 pyclipper python 的话,直接pip install pyclipper 地址:https://pypi.org/pro ...

  6. 非自交多边形的轮廓内缩外扩算法

    文章目录 1. 项目介绍 2. 算法步骤 2.1 内缩点的生成 2.2 无效内缩线段的处理 2.3 全局无效环的处理 3. 使用方法及结果演示 3.1 使用方法 3.2 结果演示 4. 不足之处 5. ...

  7. ROS::向量法外扩多边形

    ROS::向量法外扩多边形 将多边形区域的灭个边向外移动一定距离然后组成的新多边形 如上图所示针对每一个顶点分别计算外扩后的新顶点, c为当前点,p为前一个点,n为下一个点 分两种情况:1.pn中点在 ...

  8. 实现凹凸多边形外扩与内缩, 无内缩外扩混乱问题

    用于测试的三组数据点 // polygon 1pointlist.append(QVector3D( 395, 188, 0 ));pointlist.append(QVector3D( 353, 6 ...

  9. 使用Python,OpenCV进行涂鸦(绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头~)

    使用Python,OpenCV进行涂鸦(绘制文字.线.圆.矩形.椭圆.多边形轮廓.多边形填充.箭头) 1. 效果图 2. 原理 2.1 绘制线:cv2.line(canvas, (300, 0), ( ...

最新文章

  1. python语言能干什么-python语言能做什么
  2. JS提交表单页面不跳转、JS下载、动态创建from
  3. yum安装Imagick及扩展
  4. Android开发之解决NestedScrollView滑动监听兼容低版本的方法
  5. c# 批量mqtt_Paho-MQTT C#接入示例
  6. relu函数_【AI初识境】激活函数:从人工设计(sigmoid,relu)到自动搜索(swish)
  7. http://book.ifeng.com/lianzai/detail_2011_05/08/6243572_37.shtml
  8. C语言根号作用,c语言开根号(开根号编程)
  9. 即时通讯开发资料分享
  10. 低代码平台上的出入库管理
  11. Kylo调研总结(一)
  12. adb shell 小米手机_【ADB命令实战】免ROOT停用小米手机系统应用
  13. linux幻灯片制作软件,Marp(代码制作幻灯片软件)
  14. TDMS如何用Excel打开编辑
  15. 腾讯云轻量应用服务器大陆地区新套餐上线了
  16. [Unity][NGUI]悬浮点击空白区域隐藏UI
  17. 华为OD机试ACM输入输出
  18. 莫烦python pytorch_[莫烦 PyTorch 系列教程] 1.2 – 安装 PyTorch
  19. CSP之无线网络(最短路径)
  20. Python入门常用工具集合

热门文章

  1. 粘胶短纤维市场现状及未来发展趋势
  2. 如何从Google Play音乐切换到YouTube音乐
  3. php主动推送弹幕_php简陋版实现微信公众号主动推送消息
  4. 写代码必备的降噪耳机AirPods Pro,免费送
  5. 《这就是区块链》之区块链基础(5)--去中心化的意义
  6. 赋truncate权限mysql_权限管理
  7. 古月居ROS入门21讲-基础概述
  8. EC11、EC16、ECxx旋转编码器按钮软件滤波程序滤除干扰杂波51单片机C程序
  9. ATOS(阿托斯)电液比例阀
  10. 30多年前的那场芯片战争,日本是如何一败涂地的?