opencv c ++ найди вписывающий круг контура - PullRequest
0 голосов
/ 06 декабря 2018

Я хочу найти максимальный вписывающий круг контура.

Я обнаружил контур с помощью cv::findContours, и он там как vector<Point>.

Я знаю, как определить минимальный окружающий круг (cv::minEnclosingCircle), но не знаю, как получить максимальный окружающий круг.Как это сделать?

Вопрос2: Как получить вписывающие и описывающие круги с центром в центре масс?


Для пояснения я попытаюсь описать, что я имею в виду сэти окружности:

  1. мин. окружающий круг: касание объекта снаружи, центральное положение не имеет значения, минимальная площадь.
  2. окружающий круг: касание объекта снаружи, центральное положение в центре масс объекта, минимальная площадь.
  3. макс. Вмещающий круг: касание объекта изнутри, центральное положение не имеет значения, максимумплощадь.
  4. вписанный круг: касание объекта изнутри, центральное положение в центре масс объекта, максимальная площадь.

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Вы можете:

1) создать маску из своего контура

enter image description here

2) Вычислить distanceTransform намаска

enter image description here

3) Наибольшее значение - радиус, его положение - центр

enter image description here

код:

#include <opencv2\opencv.hpp>

int main()
{
    // Load image
    cv::Mat1b img = cv::imread("path_to_img", cv::IMREAD_GRAYSCALE);

    // Correct image
    cv::Mat1b bin = img < 127;

    // Find contour
    std::vector<std::vector<cv::Point>> contours;
    cv::findContours(bin, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);

    // Draw on mask
    cv::Mat1b mask(bin.rows, bin.cols, uchar(0));
    cv::drawContours(mask, contours, 0, cv::Scalar(255), cv::FILLED);

    // Distance Trasnsform
    cv::Mat1f dt;
    cv::distanceTransform(mask, dt, cv::DIST_L2, 5, cv::DIST_LABEL_PIXEL);

    // Find max value
    double max_val;
    cv::Point max_loc;
    cv::minMaxLoc(dt, nullptr, &max_val, nullptr, &max_loc);

    // Output image
    cv::Mat3b out;
    cv::cvtColor(img, out, cv::COLOR_GRAY2BGR);
    cv::circle(out, max_loc, max_val, cv::Scalar(0, 255, 0));

    return 0;
}
0 голосов
/ 06 декабря 2018

По крайней мере, я решил вычисление двух кругов с центром в центре масс (способом, подобным предложенному @Grillteller):

Point2f p_Contour_first = vp_Contour[0];
double circumCirc_Radius  = norm(p_Centroid - p_Contour_first);
double inscriCirc_Radius  = norm(p_Centroid - p_Contour_first);
for(int p = 0; p < vp_Contour.size(); p++)
{
    Point2f p_Contour_current = vp_Contour[p];
    double r = norm(p_Centroid - p_Contour_current);
    if(r < inscriCirc_Radius) inscriCirc_Radius = r;
    if(r > circumCirc_Radius) circumCirc_Radius = r;
}

Но первоначальный вопрос помнит (максимальная площадь,центральное положение не имеет значения).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...