多边形(轮廓点)等距离外扩
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. 多边形轮廓 等距离外扩

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

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

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

  3. html图片缩放6,四款css 图片按比例缩放实例(兼容ie6,7,firefox)

    使用max-width,max-height:或者min-width,min-height的css属性即可.如: 代码如下 img{max-width:100px;max-height:100px;} ...

  4. cad等比例缩放快捷键_「CAD」利用块对图形进行非等比例缩放

    之前介绍了缩放命令的使用方法,缩放命令可以把选择的图形放大或缩小一个比例,也可以按参照缩放一个比例. 需要说明的是,缩放命令是对图形等比例缩放的,图形的长宽比是锁定的.就算真的需要对图形进行非等比例缩 ...

  5. C#利用Graphics类绘制进阶--实现图片等比例缩放

    今天要用到,操作可以像画图工具一样,图片内容等比例缩放.但是在网上找了几个等比例缩放的方法,试了发现都是有问题的,基本都是你抄他,他抄你,而且也不试试这个方法到底能不能用就瞎抄.最后自己去看Graph ...

  6. 等比例缩放html5页面,css中如何做到容器按比例缩放

    本文作者:IMWeb 结一 未经同意,禁止转载 在说容易按比例缩放前,我们先说下图片按比例缩放. 对于图片,默认只设置图片的一个宽或高,那么另一个值就会按照图片真实比例缩放,如 .demo1{ wid ...

  7. Tensorflow 读取XML文件内容并对图片等比例缩放

    根据XML文件中对图片标记的信息读取,并显示在图片中. xml 文件内容: <annotation><folder>OXIIIT</folder><filen ...

  8. python 等比例缩放图片 自写

    Python等比例缩放图片 使用了 OpenCV 进行图片的读取 输入:利用 cv2.imread 函数读取的 Mat 矩阵 输出:缩放后的 Mat 矩阵(示例代码为缩放到 512x512 大小,也可 ...

  9. html5表格图片按比例缩放,JS图片等比例缩放方法完整示例

    本文实例讲述了JS图片等比例缩放方法.分享给大家供大家参考,具体如下: /p> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional ...

最新文章

  1. 华为p4支持鸿蒙功能吗_吹过的牛都一步一步给实现了!明年华为手机支持升级鸿蒙系统!...
  2. JMeter学习(六)集合点
  3. python初学篇笔记_Python学习笔记(基础篇)
  4. 点击Cell中的按钮时,如何取所在的Cell
  5. BZOJ 4810 [Ynoi2017]由乃的玉米田(莫队+bitset)
  6. ssh_exchange_identification: Connection closed by remote host解决方法
  7. CVPR 2020|超越H.265,中科大使用多帧数据改进视频压缩新方法
  8. 12. MySQL 函数
  9. linux work 账户管理,Homework Week-3 用户管理
  10. C#多线程之线程同步篇2
  11. pp助手苹果版_苹果一键刷机助手app免费版下载-一键刷机精灵下载手机版
  12. 《勘测定界界址点坐标交换格式》解析
  13. 美爆!《自然》公布2018年19张最震撼的科学图片
  14. c语言stdin输入字符,scanf如何从stdin中读取数据的
  15. RS雷达转Velodyne雷达数据Failed to find match for field ‘intensity‘
  16. html群聊插件,团队群聊.html
  17. C语言二级题库(刷题软件+60套真题+填空题+大题)2022年9月份新题第三套
  18. Apple, Steve Jobs, iCon
  19. c语言动态规划算法数塔问题,动态规划之数塔问题...
  20. 如何用服务器内存做系统盘,服务器内存扩容怎么做

热门文章

  1. VS不能编译指定版本(配置管理错误)
  2. 数组排序方法及C实现的总结
  3. Linux查看ip的命令详解
  4. 利用尾递归减少栈空间的消耗
  5. 搭建Linux0.11系统环境
  6. 使用QEMU创建虚拟机
  7. 远程链接oracle 12514,数据库建好后,本地连接正常,远程连接ORA-12514错误
  8. grpc_模型服务:流处理与使用Java,gRPC,Apache Kafka,TensorFlow的RPC / REST
  9. 第七章子查询练习_SQL学习:复杂查询
  10. plus rss.php,dedecms织梦rss输出改成全文输出