多边形轮廓 等距离外扩
多边形(轮廓点)等距离外扩
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
多边形轮廓 等距离外扩相关推荐
- 多边形或轮廓等距离外扩或收缩
参考:多边形或轮廓等距离外扩或收缩_hjk61314的博客-CSDN博客_多边形外扩 1. 需求 已知:给定一个简单多边形,多边形按照顺时针或者逆时针的数组排列, 求:内部等距离缩小或者外部放大的多边 ...
- opencv 实现多边形内缩/外扩(平移)指定距离
实现多边形内缩,内缩以后的每边仍与内缩前平行. Note: 确保函数种pList的点按逆时针顺序排列好! 此外,使用Point2f类型可以获得亚像素精度. 功能函数: /* @作用:多边形内缩 @pL ...
- 图形/多段线内缩外扩思路
图形/多段线内缩外扩思路 前言 我在网上找了很多关于多边形内缩外扩的资料,也测试了一些算法库,如Clipper,boost::geometry::buffer,其实都可以得到不错的结果. Clippe ...
- JAVA实现小精度多边形等距外扩
涉及技术 腾讯地图 jdk1.8 问题描述 开发一款应用,前端在地图上标记经纬度坐标点集合形成一个多边形,现需要在后端将多边形做一个等距外扩或者收缩. 在网上查了好多的算法,经过尝试验证,在小经度多边 ...
- 多边形轮廓等比例缩放
多边形(轮廓点)等距离外扩 1.需要安装一个python包 安装 pyclipper python 的话,直接pip install pyclipper 地址:https://pypi.org/pro ...
- 非自交多边形的轮廓内缩外扩算法
文章目录 1. 项目介绍 2. 算法步骤 2.1 内缩点的生成 2.2 无效内缩线段的处理 2.3 全局无效环的处理 3. 使用方法及结果演示 3.1 使用方法 3.2 结果演示 4. 不足之处 5. ...
- ROS::向量法外扩多边形
ROS::向量法外扩多边形 将多边形区域的灭个边向外移动一定距离然后组成的新多边形 如上图所示针对每一个顶点分别计算外扩后的新顶点, c为当前点,p为前一个点,n为下一个点 分两种情况:1.pn中点在 ...
- 实现凹凸多边形外扩与内缩, 无内缩外扩混乱问题
用于测试的三组数据点 // polygon 1pointlist.append(QVector3D( 395, 188, 0 ));pointlist.append(QVector3D( 353, 6 ...
- 使用Python,OpenCV进行涂鸦(绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头~)
使用Python,OpenCV进行涂鸦(绘制文字.线.圆.矩形.椭圆.多边形轮廓.多边形填充.箭头) 1. 效果图 2. 原理 2.1 绘制线:cv2.line(canvas, (300, 0), ( ...
最新文章
- python语言能干什么-python语言能做什么
- JS提交表单页面不跳转、JS下载、动态创建from
- yum安装Imagick及扩展
- Android开发之解决NestedScrollView滑动监听兼容低版本的方法
- c# 批量mqtt_Paho-MQTT C#接入示例
- relu函数_【AI初识境】激活函数:从人工设计(sigmoid,relu)到自动搜索(swish)
- http://book.ifeng.com/lianzai/detail_2011_05/08/6243572_37.shtml
- C语言根号作用,c语言开根号(开根号编程)
- 即时通讯开发资料分享
- 低代码平台上的出入库管理
- Kylo调研总结(一)
- adb shell 小米手机_【ADB命令实战】免ROOT停用小米手机系统应用
- linux幻灯片制作软件,Marp(代码制作幻灯片软件)
- TDMS如何用Excel打开编辑
- 腾讯云轻量应用服务器大陆地区新套餐上线了
- [Unity][NGUI]悬浮点击空白区域隐藏UI
- 华为OD机试ACM输入输出
- 莫烦python pytorch_[莫烦 PyTorch 系列教程] 1.2 – 安装 PyTorch
- CSP之无线网络(最短路径)
- Python入门常用工具集合