【问题标题】:Is there a way to detect if a circle is connected to another circle with a line in opencv?有没有办法检测一个圆是否与另一个圆在opencv中的一条线相连?
【发布时间】:2019-07-19 11:54:16
【问题描述】:

我正在尝试编写一个 Maya 插件,将 UV 空间中的 2D 骨骼绘图重新创建到 3D 空间。我从一个带有这张图片的简单飞机开始:

我需要的是两个找到圆圈并创建一个层次结构。

我尝试了 Nuzhny 方法,但我得到了如下水平线:

我的代码:

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);

【问题讨论】:

  • 更改索引:pts[0] + pts[3] 和 pts[1] + pts[2]

标签: c++ opencv image-processing


【解决方案1】:
  1. cvtColor 转 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. 嵌套循环为每个线点找到最近的圆。

【讨论】:

  • 我尝试了你的方法,但我得到了水平线。这是我的代码:
  • 对不起,它需要更改 pts 中的索引 - 我已修复
猜你喜欢
  • 2015-05-11
  • 1970-01-01
  • 1970-01-01
  • 2022-11-13
  • 1970-01-01
  • 1970-01-01
  • 2013-01-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多