首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >opencv c++找到等高线的铭文圆

opencv c++找到等高线的铭文圆
EN

Stack Overflow用户
提问于 2018-12-06 06:53:08
回答 3查看 3.1K关注 0票数 5

我想找到的最大铭文圆的轮廓。

我已经用cv::findContours检测到了轮廓,它是作为一个vector<Point>存在的。

我知道如何检测最小包围圆(cv::minEnclosingCircle),但不知道如何得到最大封闭圆。怎么做?

Question2:我如何得到以质心为中心的铭文和外圈?

为了澄清,我试图用这些圆圈来描述我的意思:

  1. min包围圈:从外部接触物体,中心位置不重要,最小面积。
  2. 外接圆:从外接触物体,在物体质心上的中心位置,最小面积。
  3. 最大闭合圈:从内接触物体,中心位置不重要,最大面积。
  4. 铭文圆:从内接触物体,中心位置在物体质心,最大面积。
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-12-06 10:07:59

您可以:

1)根据你的轮廓创建一个面具

2)在掩码上计算distanceTransform

3)最高值为半径,其位置为中心。

代码:

代码语言:javascript
复制
#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;
}
票数 10
EN

Stack Overflow用户

发布于 2018-12-06 09:43:28

至少,我解决了以质心为中心的两个圆圈的计算(类似于@Grillteller建议的方式):

代码语言:javascript
复制
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;
}

但最初的问题记住(最大面积,中心位置不重要)。

票数 1
EN

Stack Overflow用户

发布于 2022-08-12 21:28:47

@Miki的回答很棒,非常有用,我只是花了一点时间把它翻译成python,我想我也应该把它放在这里

代码语言:javascript
复制
#get maximum inscribed circle
#my input image is called "frame"
#get threshold image from frame

ret, thresh = cv2.threshold(frame, 100, 255, cv2.THRESH_BINARY)
contours,hierarchy = cv2.findContours(thresh, 1, cv2.CHAIN_APPROX_NONE)

#create blank mask
mask = np.zeros(frame.shape[:2], dtype="uint8")
cv2.drawContours(mask, contours, -1, 255, -1)
dist = cv2.distanceTransform(mask, cv2.DIST_L2, 0)
NULL,max_val,NULL,max_indx=cv2.minMaxLoc(dist)

(x,y),radius = max_indx, max_val

#draw circle on original image
cv2.circle(frame, (x,y), radius, (0,255,0), 2)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53646022

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档