已知一个由cv::Point2f点集组成的轮廓,扩大轮廓,得到点集
using CvContour = std::vector<cv::Point2f>;
using CvContouri = std::vector<cv::Point>;
using CvContoursi = std::vector<CvContouri>;
std::pair<cv::Point2f, cv::Point2f> findBoundingBox(const CvContour& contour) {
float min_x = FLT_MAX, min_y = FLT_MAX, max_x = FLT_MIN, max_y = FLT_MIN;
for (auto &p : contour) {
if (p.x < min_x) {
min_x = p.x;
}
if (p.y < min_y) {
min_y = p.y;
}
if (p.x > max_x) {
max_x = p.x;
}
if (p.y > max_y) {
max_y = p.y;
}
}
std::pair<cv::Point2f, cv::Point2f> ret =
std::pair<cv::Point2f, cv::Point2f>(cv::Point2f(min_x, min_y), cv::Point2f(max_x, max_y));
return ret;
}
CvContour expandContour(const CvContour &contour, const int cv_size) {
std::pair<cv::Point2f, cv::Point2f> bound = findBoundingBox(contour);
CvContouri ret_contour;
CvContour out_contour;
int expand_screen = cv_size * 4;
for (auto &p : contour) {
cv::Point temp(int(expand_screen + (p.x - bound.first.x) * 100), int(expand_screen + (p.y - bound.first.y) * 100));
ret_contour.emplace_back(temp);
}
cv::Size background_size((int)(abs(bound.second.y - bound.first.y) * 100) + expand_screen * 2, (int)(abs(bound.second.x - bound.first.x) * 100) + expand_screen * 2);
cv::Mat background(background_size, CV_8U, cv::Scalar(0));
CvContoursi ret_contours;
ret_contours.emplace_back(ret_contour);
cv::drawContours(background, ret_contours, -1, cv::Scalar(255), CV_FILLED);
cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(cv_size , cv_size) * 2);
cv::dilate(background, background, element);
std::vector<std::vector<cv::Point>> all_contours;
cv::findContours(background, all_contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
for (int i = 0; i < all_contours.size(); i++) {
for (int j = 0; j < all_contours[i].size(); j++) {
cv::Point2f temp_point =
(cv::Point2f(all_contours[i][j] - cv::Point(20, 20)) / 100.f) + cv::Point2f(bound.first.x, bound.first.y);
out_contour.emplace_back(temp_point);
}
}
return out_contour;
}