有没有办法检测一个圆是否在opencv中用线连接到另一个圆?

时间:2019-02-26 01:04:45

标签: c++ opencv image-processing

我正在尝试编写Maya插件,该插件可将UV空间中的骨骼2D图重新创建为3D空间。我从这张图片的简单平面开始:enter image description here

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

我尝试过Nuzhny方法,但得到的水平线如下: 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 :(得分:0)

  1. cvtColor转换为HSV。

  2. inRange(redFrom,redTo)+ findContours查找红色圆圈。

  3. inRange(whiteFrom,whiteTo)+ findContours查找白线。

  4. 线到线的轮廓:

    cv :: RotatedRect框= 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. 嵌套循环为每个线点找到一个最近的圆。