目录
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 pyclipper
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 # 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 solution
if __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