多边形轮廓等比例缩放
多边形(轮廓点)等距离外扩
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 = 10
contour = 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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
调用示例子:
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 = 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)
1
2
3
4
5
6
7
8
9
结果展示:
3.轮廓点等比例缩放
def perimeter(poly):
p = 0
nums = poly.shape[0]
for i in range(nums):
p += abs(np.linalg.norm(poly[i % nums] - poly[(i + 1) % nums]))
return p
def 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 = 10
if perimeter_poly:
d = area_poly * (1 - ratio * ratio) / perimeter_poly
pco.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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
调用示范:
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)
1
2
3
4
5
6
7
8
其中 pco.MiterLimit = 10这个参数默认是2,如果是默认的值结果图第一个,改成10的话,结果图就是第二个,是一个尖角的区别
4.图形轮廓点的旋转
# 获取一个形状的质心
def get_centroid(coord):
coord = np.array(coord)
shape = coord.shape
if len(shape) == 1 and len(coord) == 2: # point
return coord
if len(shape) == 1 and len(coord) == 4: # bounding box
return 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).centroid
else:
cen = Polygon(coord).centroid
return tuple(map(int, [cen.x, cen.y]))
elif len(shape) == 3 and shape[1:] == (1, 2): # contour
cen = Polygon(coord.squeeze()).centroid
return 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_point
x2, y2 = origin_point
y1 = row - y1
y2 = row - y2
x = (x1 - x2) * math.cos(math.pi / 180.0 * angle) - (y1 - y2) * math.sin(math.pi / 180.0 * angle) + x2
y = (x1 - x2) * math.sin(math.pi / 180.0 * angle) + (y1 - y2) * math.cos(math.pi / 180.0 * angle) + y2
x = x
y = row - y
return [x, y]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
调用示范
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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
结果图:
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_length
ratio = 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_ext
def 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
————————————————
版权声明:本文为CSDN博主「Cecilia_lu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43624833/article/details/112919141
多边形轮廓等比例缩放相关推荐
- 多边形轮廓 等距离外扩
多边形(轮廓点)等距离外扩 1.需要安装一个python包 安装 pyclipper python 的话,直接pip install pyclipper 地址:https://pypi.org/pro ...
- 使用Python,OpenCV进行涂鸦(绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头~)
使用Python,OpenCV进行涂鸦(绘制文字.线.圆.矩形.椭圆.多边形轮廓.多边形填充.箭头) 1. 效果图 2. 原理 2.1 绘制线:cv2.line(canvas, (300, 0), ( ...
- html图片缩放6,四款css 图片按比例缩放实例(兼容ie6,7,firefox)
使用max-width,max-height:或者min-width,min-height的css属性即可.如: 代码如下 img{max-width:100px;max-height:100px;} ...
- cad等比例缩放快捷键_「CAD」利用块对图形进行非等比例缩放
之前介绍了缩放命令的使用方法,缩放命令可以把选择的图形放大或缩小一个比例,也可以按参照缩放一个比例. 需要说明的是,缩放命令是对图形等比例缩放的,图形的长宽比是锁定的.就算真的需要对图形进行非等比例缩 ...
- C#利用Graphics类绘制进阶--实现图片等比例缩放
今天要用到,操作可以像画图工具一样,图片内容等比例缩放.但是在网上找了几个等比例缩放的方法,试了发现都是有问题的,基本都是你抄他,他抄你,而且也不试试这个方法到底能不能用就瞎抄.最后自己去看Graph ...
- 等比例缩放html5页面,css中如何做到容器按比例缩放
本文作者:IMWeb 结一 未经同意,禁止转载 在说容易按比例缩放前,我们先说下图片按比例缩放. 对于图片,默认只设置图片的一个宽或高,那么另一个值就会按照图片真实比例缩放,如 .demo1{ wid ...
- Tensorflow 读取XML文件内容并对图片等比例缩放
根据XML文件中对图片标记的信息读取,并显示在图片中. xml 文件内容: <annotation><folder>OXIIIT</folder><filen ...
- python 等比例缩放图片 自写
Python等比例缩放图片 使用了 OpenCV 进行图片的读取 输入:利用 cv2.imread 函数读取的 Mat 矩阵 输出:缩放后的 Mat 矩阵(示例代码为缩放到 512x512 大小,也可 ...
- html5表格图片按比例缩放,JS图片等比例缩放方法完整示例
本文实例讲述了JS图片等比例缩放方法.分享给大家供大家参考,具体如下: /p> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional ...
最新文章
- 华为p4支持鸿蒙功能吗_吹过的牛都一步一步给实现了!明年华为手机支持升级鸿蒙系统!...
- JMeter学习(六)集合点
- python初学篇笔记_Python学习笔记(基础篇)
- 点击Cell中的按钮时,如何取所在的Cell
- BZOJ 4810 [Ynoi2017]由乃的玉米田(莫队+bitset)
- ssh_exchange_identification: Connection closed by remote host解决方法
- CVPR 2020|超越H.265,中科大使用多帧数据改进视频压缩新方法
- 12. MySQL 函数
- linux work 账户管理,Homework Week-3 用户管理
- C#多线程之线程同步篇2
- pp助手苹果版_苹果一键刷机助手app免费版下载-一键刷机精灵下载手机版
- 《勘测定界界址点坐标交换格式》解析
- 美爆!《自然》公布2018年19张最震撼的科学图片
- c语言stdin输入字符,scanf如何从stdin中读取数据的
- RS雷达转Velodyne雷达数据Failed to find match for field ‘intensity‘
- html群聊插件,团队群聊.html
- C语言二级题库(刷题软件+60套真题+填空题+大题)2022年9月份新题第三套
- Apple, Steve Jobs, iCon
- c语言动态规划算法数塔问题,动态规划之数塔问题...
- 如何用服务器内存做系统盘,服务器内存扩容怎么做
热门文章
- VS不能编译指定版本(配置管理错误)
- 数组排序方法及C实现的总结
- Linux查看ip的命令详解
- 利用尾递归减少栈空间的消耗
- 搭建Linux0.11系统环境
- 使用QEMU创建虚拟机
- 远程链接oracle 12514,数据库建好后,本地连接正常,远程连接ORA-12514错误
- grpc_模型服务:流处理与使用Java,gRPC,Apache Kafka,TensorFlow的RPC / REST
- 第七章子查询练习_SQL学习:复杂查询
- plus rss.php,dedecms织梦rss输出改成全文输出