Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

opencv c++ find inscribing circle of a contour

I want to find the maximum inscribing circle of contour.

I have detected the contour with cv::findContours and it is there as a vector<Point>.

I know how to detect the minimum enclosing circle (cv::minEnclosingCircle), but not how to get the maximum inclosing circle. How to do this?

Question2: How do i get the inscribing and circumscribing circles centered on the center of mass?


For clarification, i try to describe, what i mean with these circels:

  1. min enclosing circle: touching object from outside, center position doesn't matter, minimum area.
  2. circumscribing circle: touching object from outside, center position on the center of mass of the object, minimum area.
  3. max inclosing circle: touching object from inside, center position doesn't matter, maximum area.
  4. inscribing circle: touching object from inside, center position on the center of mass of the object, maximum area.
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can:

1) create a mask from your contour

enter image description here

2) Compute the distanceTransform on the mask

enter image description here

3) The highest value is the radius, its position is the center

enter image description here

Code:

#include <opencv2opencv.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;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...