pyclipper和ClipperLib操作多边型
目录
1. 等距离缩放多边形
1.1 python
1.2 c++
1. 等距离缩放多边形
1.1 python
环境配置pip install opencv-python opencv-contrib-python
pip install pyclipper
pip install numpy
import cv2
import numpy as np
import pyclipperdef equidistant_zoom_contour(contour, margin):"""等"距离"缩放多边形轮廓点:param contour: 一个图形的轮廓格式[[[x1, x2]],...],shape是(-1, 1, 2):param margin: 轮廓外扩的像素距离,margin正数是外扩,负数是缩小:return: 外扩后的轮廓点"""pco = pyclipper.PyclipperOffset()# 参数限制,默认成2,这里设置大一些,主要是用于多边形的尖角是否用圆角代替pco.MiterLimit = 10 # 2是圆角,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 solutionif __name__ == '__main__':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, [contour1], True, (0, 255, 0), 3)cv2.polylines(img, [poly], True, (0, 0, 255), 3)cv2.namedWindow("img", cv2.WINDOW_NORMAL), cv2.imshow("img", img), cv2.waitKey()
参数MiterLimit=10是尖角(左图),默认值是2,圆角(右图)
1.2 c++
第一版clipper: Download Clipper
最新版clipper2: https://github.com/AngusJohnson/Clipper2
官方介绍:https://angusj.com/clipper2/Docs/Overview.htm
(1)这里使用旧版clipper,下载后解压
(2)vs2019配置clipper环境,只需要添加包含目录即可。
(3) 添加现有clipper头文件和源码 clipper.cpp和clipper.hpp
#include <iostream>
#include <vector>
#include <clipper.hpp>using namespace ClipperLib;std::vector<IntPoint> equidistant_zoom_contour(const std::vector<std::vector<IntPoint>>& contours, double margin) {ClipperOffset co;co.MiterLimit = 10; // 默认2圆角,10尖角co.AddPaths(contours, jtMiter, etClosedPolygon);Paths solution;co.Execute(solution, margin);std::vector<IntPoint> result;for (const auto& path : solution) {result.insert(result.end(), path.begin(), path.end());}return result;
}int main() {Paths poly = {{{200, 200}, {200, 300}, {400, 350}, {350, 200}, {300, 200}, {200, 100}}};double margin = 20.0;std::vector<IntPoint> contour1 = equidistant_zoom_contour(poly, margin);cv::Mat img = cv::Mat::zeros(500, 500, CV_8UC3);std::vector<std::vector<cv::Point>> contours_cv(1);for (const auto& point : contour1) {contours_cv[0].emplace_back(point.X, point.Y);}cv::polylines(img, contours_cv, true, cv::Scalar(0, 255, 0), 3);contours_cv.clear();for (const auto& path : poly) {std::vector<cv::Point> contour_cv;for (const auto& point : path) {contour_cv.emplace_back(point.X, point.Y);}contours_cv.push_back(contour_cv);}cv::polylines(img, contours_cv, true, cv::Scalar(0, 0, 255), 3);cv::namedWindow("img", cv::WINDOW_NORMAL);cv::imshow("img", img);cv::waitKey(0);return 0;
}
MiterLimit默认2圆角(左图),10尖角 (右图)
待续。。。
参考:https://www.cnblogs.com/01black-white/p/15292193.html