Есть ли способ определить, связан ли круг с другим кругом линией в opencv? - PullRequest
0 голосов
/ 26 февраля 2019

Я пытаюсь написать плагин Maya, который воссоздает двумерный рисунок костей в УФ-пространстве в 3D-пространстве.Я начинаю с простой плоскости с этим изображением: enter image description here

Мне нужно найти два круга и создать иерархию.

Я попробовал Нужный подходно я получаю горизонтальные линии, например: enter image description here

Мой код:

Mat image;
image = imread("c:/pjs/sk.jpg");   // Read the file
cv::Mat hsv_image;
cv::cvtColor(image, hsv_image, cv::COLOR_BGR2HSV);
cv::Mat lower_red_hue_range;
cv::Mat upper_red_hue_range;
cv::Mat white_hue_range;

// Разделяем линии и круги

cv::inRange(hsv_image, cv::Scalar(0, 100, 100), cv::Scalar(10, 255, 255), lower_red_hue_range);
cv::inRange(hsv_image, cv::Scalar(160, 100, 100), cv::Scalar(179, 255, 255), upper_red_hue_range);
cv::inRange(hsv_image, cv::Scalar(0, 0, 20), cv::Scalar(0, 0, 255), white_hue_range);
cv::Mat red_hue_image;
cv::addWeighted(lower_red_hue_range, 1.0, upper_red_hue_range, 1.0, 0.0, red_hue_image);
cv::GaussianBlur(red_hue_image, red_hue_image, cv::Size(9, 9), 2, 2);

// Определить круги

std::vector<cv::Vec3f> circles;
cv::HoughCircles(red_hue_image, circles, HOUGH_GRADIENT, 1, red_hue_image.rows / 8, 100, 20, 0, 0);
if (circles.size() == 0) std::exit(-1);
for (size_t current_circle = 0; current_circle < circles.size(); ++current_circle) {
    cv::Point center(std::round(circles[current_circle][0]), std::round(circles[current_circle][1]));
    int radius = std::round(circles[current_circle][2]);

    cv::circle(image, center, radius, cv::Scalar(0, 255, 0), 5);

}

// Получить контуры

cv::threshold(white_hue_range, white_hue_range, 11, 255, cv::THRESH_BINARY);
cv::Mat element = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(3, 3));
element = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(20, 20));
cv::dilate(white_hue_range, white_hue_range, element);
cv::dilate(white_hue_range, white_hue_range, element);
cv::erode(white_hue_range, white_hue_range, element);
cv::erode(white_hue_range, white_hue_range, element);
element = cv::getStructuringElement(cv::MORPH_CROSS, cv::Size(5, 5));
cv::dilate(white_hue_range, white_hue_range, element);

Mat gray;
gray = white_hue_range;
Canny(gray, gray, 40, 100, 7);
/// Find contours   
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
RNG rng(12345);
findContours(gray, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
/// Draw contours
Mat drawing = Mat::zeros(gray.size(), CV_8UC3);
for (int i = 0; i < contours.size(); i++)
{
    Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
    drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
}

// Получить линии

vector<vector<Point2f> > lines;
vector<Point> approx;
for (unsigned int i = 0; i < contours.size(); i++)
{

    if (contours[i].size() > 4) {
        //cv::Rect box =  cv::fitEllipse(contours[i]);
        cv::RotatedRect box = cv::fitEllipseAMS(contours[i]);

        cv::Point2f pts[4];
        box.points(pts);
        vector<cv::Point2f> line_pts;
        line_pts.resize(2);
        line_pts[0] = (pts[0] + pts[1]) / 2;
        line_pts[1] = (pts[2] + pts[3]) / 2;
        lines.push_back(line_pts);

    }

}

for (int i = 0; i < lines.size(); i++)
{
    line(image, lines[i].at(0), lines[i].at(1), 128, 4, LINE_8, 0);
}
imshow("Result window", image);

1 Ответ

0 голосов
/ 26 февраля 2019
  1. cvtЦвет к HSV.

  2. inRange (redFrom, redTo) + findContours для поиска красных кружков.

  3. inRange (whiteFrom, whiteTo) + findContours для поиска белых линий.

  4. Контур линии на линию:

    cv :: RotatedRect box = cv :: fitEllipse (line_contours [i]);

    cv :: Point2f pts [4];

    box.points (pts);

    cv :: Point2f line_pts [2];

    line_pts [0] = (pts [0] + pts [3]) / 2;

    line_pts [1] = (pts [1] + pts [2]) / 2;

  5. Вложенные циклы для поиска ближайшего круга для каждой точки линии.

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