使用 OpenCV 查找重叠/复杂的圆

2024-05-03

我想计算红圈半径(图2)。我在使用 OpenCV 的 HoughCircles 找到这些圆圈时遇到了麻烦。如图所示。 2 我只能使用 HoughCircles 找到中心以黑色显示的小圆圈。

original pic1 fig 2. red

由于我知道红色圆圈的中心(与红色圆圈相同),有没有办法简单地计算红色圆圈的半径?

是否也可以有一种通用的方法来计算更复杂的图像(例如下图)上的圆半径:

编辑:这是获得图 2 后我的代码的有趣部分:

threshold(maskedImage, maskedImage, thresh, 255, THRESH_BINARY_INV | THRESH_OTSU);
    std::vector<Vec3f> circles;
// Canny(maskedImage, maskedImage, thresh, thresh * 2, 3);

HoughCircles(maskedImage, circles, CV_HOUGH_GRADIENT, 1, src_gray.rows / 4, cannyThreshold, accumulatorThreshold, 0, 0);

Mat display = src_display.clone();
for (size_t i = 0; i < circles.size(); i++)
{
    Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
    int radius = cvRound(circles[i][2]);
    // circle center
    circle(display, center, 3, Scalar(0, 255, 0), -1, 8, 0);
    // circle outline
    circle(display, center, radius, Scalar(0, 0, 255), 3, 8, 0);
}

我尝试使用 cannyThreshold 和累加器进行游戏,但没有结果。真实图像大 5 倍。这里a link https://drive.google.com/file/d/0B_Yv8cvdcD-bRDBsSEJuYTJfdDg/edit?usp=sharing例如阈值后的 1。

Thanks


您已经知道图像中的较小圆圈(您用黑色绘制)。

  • 使用这些圆圈准备蒙版图像,以便具有较小圆圈的区域将具有非零像素。我们将称之为mask:
  • 在原始图像中,用深色(例如黑色)填充这些圆形区域。这将产生如图 2 所示的图像。我们将其称为filled
  • 阈值filled图像以获得暗区域。我们将称之为binary。为此,您可以使用 Otsu 阈值。结果看起来像这样:
  • 对其进行距离变换binary图像。为此,请使用准确的距离估计方法。我们称之为dist。它看起来像这样。为了更清晰起见,彩色图只是一张热图:
  • Use the mask获得峰值区域dist。每个此类区域的最大值应该给出较大圆的半径。您还可以对这些区域进行一些处理,以获得更合理的半径值,而不仅仅是选取最大值。
  • 为了选择区域,您可以找到区域的轮廓mask然后从中提取该区域dist图像,或者,因为您已经通过应用霍夫圆变换知道了较小的圆,所以从每个圆中准备一个掩模并从dist图像。我不确定您是否可以通过给出掩码来计算最大值或其他统计数据。 Max 肯定会起作用,因为其余像素都是 0。如果将这些像素提取到另一个数组,您也许可以计算该区域的统计数据。

下图显示了这样的掩模和从中提取的区域dist。为此,我得到的最大值约为 29,这与该圆的半径一致。请注意,图像未按比例绘制。

圆的掩模,从中提取的区域dist

这是代码(我没有使用霍夫圆变换):

    Mat im = imread(INPUT_FOLDER_PATH + string("ex1.jpg"));

    Mat gray;
    cvtColor(im, gray, CV_BGR2GRAY);

    Mat bw;
    threshold(gray, bw, 0, 255, CV_THRESH_BINARY|CV_THRESH_OTSU);
    // filtering smaller circles: not using hough-circles transform here. 
    // you can replace this part with you hough-circles code.
    vector<int> circles;
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(bw, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
    for(int idx = 0; idx >= 0; idx = hierarchy[idx][0])
    {
        Rect rect = boundingRect(contours[idx]);
        if (abs(1.0 - ((double)rect.width/rect.height) < .1))
        {
            Mat mask = Mat::zeros(im.rows, im.cols, CV_8U);
            drawContours(mask, contours, idx, Scalar(255, 255, 255), -1);
            double area = sum(mask).val[0]/255;
            double rad = (rect.width + rect.height)/4.0;
            double circArea = CV_PI*rad*rad;
            double dif = abs(1.0 - area/circArea);
            if (dif < .5 && rad < 50 && rad > 30)   // restrict the radius
            {
                circles.push_back(idx); // store smaller circle contours
                drawContours(gray, contours, idx, Scalar(0, 0, 0), -1); // fill circles
            }
        }
    }

    threshold(gray, bw, 0, 255, CV_THRESH_BINARY_INV|CV_THRESH_OTSU);

    Mat dist, distColor, color;
    distanceTransform(bw, dist, CV_DIST_L2, 5);
    double max;
    Point maxLoc;
    minMaxLoc(dist, NULL, &max);
    dist.convertTo(distColor, CV_8U, 255.0/max);
    applyColorMap(distColor, color, COLORMAP_JET);
    imshow("", color);
    waitKey();

    // extract dist region corresponding to each smaller circle and find max
    for(int idx = 0; idx < (int)circles.size(); idx++)
    {
        Mat masked;
        Mat mask = Mat::zeros(im.rows, im.cols, CV_8U);
        drawContours(mask, contours, circles[idx], Scalar(255, 255, 255), -1);
        dist.copyTo(masked, mask);
        minMaxLoc(masked, NULL, &max, NULL, &maxLoc);
        circle(im, maxLoc, 4, Scalar(0, 255, 0), -1);
        circle(im, maxLoc, (int)max, Scalar(0, 0, 255), 2);
        cout << "rad: " << max << endl;
    }
    imshow("", im);
    waitKey();

结果(缩放):

希望这可以帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 OpenCV 查找重叠/复杂的圆 的相关文章

  • opencv形态扩张滤波器作为最大滤波器

    就像中值滤波器的定义一样 我可以将 最大滤波器 定义为局部窗口 例如dst x y max 3x3 局部窗口像素 但我在opencv中找不到这样的过滤器 最接近的是 dilate 函数 然后我使用 dilate 函数的默认配置 但结果不正确
  • 在discord.py中访问成员的横幅

    我正在制作图像配置文件命令 我想为此访问会员的横幅 我们有什么办法可以在discord py 中做到这一点吗 如果不清楚我所说的横幅是什么意思 那么蓝色背景的图像就是横幅 我想访问它 在discord py v2 0中你可以使用 You m
  • 当我将鼠标移到 Mat 关键字上时,Visual Studio 2017 冻结(OpenCv 3.4.1)

    我想在 Visual Studio 2017 中开发 openCv 项目 我下载了 opencv 预构建库并进行了必要的设置 那是 1 我添加了系统路径 build x64 vc14 bin 2 在 Visual Studio 中的项目属性
  • 使用 ffmpeg 或 OpenCV 处理原始图像

    看完之后维基百科页面 http en wikipedia org wiki Raw image format原始图像格式 是任何图像的数字负片 为了查看或打印 相机图像传感器的输出具有 进行处理 即转换为照片渲染 场景 然后以标准光栅图形格
  • OpenCV Visual Studio ntdll.dll

    我尝试在 Visual Studio 2013 上使用 OpenCV 2 4 10 创建一个项目 但由于以下异常 到目前为止我运气不佳 请建议帮助 TIA letstryitonemoretime exe Win32 Loaded C Us
  • 如何使用 python 在白色背景上裁剪图像?

    我正在扫描旧照片 因此我有来自扫描仪的图像和白色背景 我的目的是拍照 去除白色背景 我怎样才能做到这一点 An example picture is the following 我的简单方法 import os import time fr
  • 为什么我无法在 Mac 12.0.1 (Monterey) 上使用 pip 安装 OpenCV? [复制]

    这个问题在这里已经有答案了 当我尝试使用 python pip 安装 OpenCV 时 它显示了以下内容 Remainder of file ignored Requirement already satisfied pip in Libr
  • 从图像坐标获取对象的世界坐标

    I have been following this http docs opencv org modules calib3d doc camera calibration and 3d reconstruction html docume
  • 如何使用 python、openCV 计算图像中的行数

    我想数纸张 所以我正在考虑使用线条检测 我尝试过一些方法 例如Canny HoughLines and FLD 但我只得到处理过的照片 我不知道如何计算 有一些小线段就是我们想要的线 我用过len lines or len contours
  • setImageCompressionQuality 与 setCompressionQuality 之间有什么区别 - Imagick

    我在Imagick中找到了两种设置图像压缩质量的方法 A 设置图像压缩质量 B 设置压缩质量 所以我想知道哪一个是最好的以及为什么在以下条件下 我读到了setCompressionQuality方法仅适用于新图像 我正在尝试压缩文件 jpe
  • 在 Visual Studio 中调试非托管 C++ 图像

    我确实在 Visual Studio 2010 下的非托管 C 上编写了大量图像处理代码 其中涉及许多不同的图像 我希望能够在逐步调试时像简单标识符一样轻松地观看它们 我当前的解决方案是使用一些在 Matlab 控制台中导出图像的函数 可以
  • Python 或 C 语言中的 Matlab / Octave bwdist()

    有谁知道 Matlab Octave bwdist 函数的 Python 替代品 此函数返回给定矩阵的每个单元格到最近的非零单元格的欧几里得距离 我看到了一个 Octave C 实现 一个纯 Matlab 实现 我想知道是否有人必须用 AN
  • 如何去除给定图像中的噪声,使 ocr 输出完美?

    我已经对这个孟加拉文本图像进行了大津阈值处理 并使用 tesseract 进行 OCR 但输出非常糟糕 我应该应用什么预处理来消除噪音 我也想校正图像 因为它有轻微的倾斜 我的代码如下 import tesserocr from PIL i
  • OpenCV IP 相机应用程序崩溃 [h264 @ 0xxxxx] 访问单元中缺少图片

    我在 cpp 中有一个 opencv 应用程序 它使用 opencv 的简单结构捕获视频流并将其保存到视频文件中 它与我的网络摄像头完美配合 但是 当我运行它从 IP 摄像机捕获流时 它可能会在大约十秒后崩溃 我的编译命令是 g O3 IP
  • 使用 OpenCV 改进特征点匹配

    我想匹配立体图像中的特征点 我已经用不同的算法找到并提取了特征点 现在我需要一个良好的匹配 在本例中 我使用 FAST 算法进行检测和提取 BruteForceMatcher用于匹配特征点 匹配代码 vector lt vector
  • 从包含带边框的表格的图像中提取表格结构

    我正在尝试提取下表中的单元格位置 应用自适应阈值处理后 我能够获得细胞位置周围的轮廓 并且 HoughLines 获得垂直和水平结构元素 这是我的代码 img cv2 imread os path join img path file im
  • 如何使用 opencv python 计算乐高积木上的孔数?

    我正在开发我的 python 项目 我需要计算每个乐高积木组件中有多少个孔 我将从输入 json 文件中获取有关需要计算哪个程序集的信息 如下所示 img 001 red 0 blue 2 white 1 grey 1 yellow 1 r
  • 同时从多个流中捕获、最佳方法以及如何减少 CPU 使用率

    我目前正在编写一个应用程序 该应用程序将捕获大量 RTSP 流 在我的例子中为 12 个 并将其显示在 QT 小部件上 当我超过大约 6 7 个流时 问题就会出现 CPU 使用率激增并且出现明显的卡顿 我认为它不是 QT 绘制函数的原因是因
  • android中根据屏幕尺寸计算图像尺寸

    我正在尝试根据屏幕尺寸计算图像高度和宽度 我从后端获取 5 x 7 尺寸的图像 为了将像素乘以 72 进行转换 我有 360 X 504 尺寸的图像 对于 360 X 504 我的动态透明矩形区域将显示为 1 223 x 1 179 即 8
  • 如何使用 opencv.omnidir 模块对鱼眼图像进行去扭曲

    我正在尝试使用全向模块 http docs opencv org trunk db dd2 namespacecv 1 1omnidir html用于对鱼眼图像进行扭曲处理Python 我正在尝试适应这一点C 教程 http docs op

随机推荐

  • 如何使用 ActionText 显示嵌入视频

    我正在尝试在 Rails 6 上使用 ActionText 显示嵌入式视频 无论是在 WYSIWYG Trix 中还是在渲染的内容中 但是 ActionText 渲染器会过滤所有原始 html 代码 并强制我使用 JS 在渲染内容中显示 i
  • 从节点内部开始一条边

    digraph foo a label
  • Linq 警告

    Linq 是 NET 的一个很棒的补充 我发现它在很多情况下都对我很有帮助 尽管我才刚刚开始学习如何使用 Linq 然而 在阅读有关 Linq 的文章时 我发现开发人员需要留意一些微妙的事情 否则可能会导致麻烦 我已经添加了一个明确的警告
  • Bash或Python,当打印字符到终端时,如何更改固定位置的字符?

    我想知道的事情应该是非常 基本 的 但这是我脑海中很长一段时间的问题 不知道窍门在哪里 假设在一个耗时的程序中 或者bash or Python 我必须打印出运行时的进度百分比 基本上我想打印1 一段时间后 我打印2 等等 我想要 2 完全
  • Boost C++ 和 Android 3

    我尝试用谷歌和SO搜索 到目前为止 我只能找到相互矛盾的信息 如果 Boost 和 Android 结合太难 也许有替代品 我对 smart ptr 线程 函数 lexical cast string algo 和容器特别感兴趣 任何意见都
  • 如何在android中使用jquery和phonegap打开pdf文件?

    最近我正在为 Android 构建一个应用程序 我正在使用phonegap 来做同样的事情 一切都运行良好 除了一个问题 即我无法在 android 中使用 jquery 打开 pdf 文件 我已经尝试了很多做同样的事情 但我无法做到这一点
  • 从主目录隐藏八度工作区文件

    我想更改文件octave workspace从我的主目录中 只需将其重命名为 octave workspace 如何设法使 Octave 识别具有此新名称的工作区文件 或创建一个新文件 Thanks 这就是该组织的目的octave core
  • 哪种 ZeroMQ 模式最适合异步套接字对?

    我有一个服务器 在亚马逊上运行 和一个连接到它的客户端 建立连接后 客户端和服务器仅相互通信并发送消息 e g 1 Client gt Server 2 Client gt Server 3 Client lt Server 4 Clien
  • Android:向系统添加自定义字体

    我知道如何在应用程序中使用自定义字体 但我想做的是在系统范围内添加自定义字体 就像在 Windows 上添加新字体一样 如果没有官方的方法 我应该阅读android源代码的哪个模块 我必须更改 android 源代码并构建它以支持自定义字体
  • 运行添加迁移时无法加载程序集 Microsoft.EntityFrameworkCore.Design

    我使用以下 csproj 创建了一个类库项目
  • 如何将 JSON 响应映射到 Angular 4 中的模型

    我已经尝试了很多 但无法将端点响应映射到我的模型 我正在使用 HttpClient 和 Angular4 我从服务中获取了数据 但它没有正确映射到我的模型类 我有以下 JSON 服务正在返回 result id 1 type User co
  • Android 中 Activity 之间的对象共享

    您好 我有一个关于在整个应用程序中传递对象的问题 假设我想在整个应用程序中拥有一个大的自定义对象 该对象将被多个活动和服务使用 我一开始做的就是这样的 首先 我创建了一个 Application 类并定义了一个单例对象 public cla
  • 代码签名身份 <名称> 与任何有效的、未过期的代码签名证书不匹配

    我希望有人能帮我解决这个令人抓狂的问题 我和我的朋友正在开发一个 mac 商店应用程序 托管在 github 上 一个月前 我们使用他的开发中心帐户从他的机器上发布了该应用程序 我最近将源代码从 github 拉到我的机器上 以进行更新 但
  • 使用 php5-geoip 和 Maxmind 数据库获取 IPv6 支持

    我按照这些相同的步骤进行了 geoip 设置 http php net manual en geoip setup php http php net manual en geoip setup php wget http geolite m
  • Spring 3.1 MVC - 表单处理工作流程最佳实践

    目前我正在尝试了解 Spring MVC 3 1 中表单提交 验证 错误处理的正确工作流程 不 我有一些问题 保留表单错误 通过重定向绑定模型的正确方法是什么 是否有内置方法 我还没有找到 我知道我可以使用 Spring 表单标签和 JSR
  • 选择给定日期范围内的所有月份,包括值为 0 的月份

    我正在尝试编写一个 MySQL 查询来获取给定日期之间所有月份的每月平均值 我的想法是这样的 查询 类似 SELECT AVG value1 as avg value 1 AVG value2 as avg value 2 MONTH sa
  • JavaScript“可写”属性描述符如何工作?

    为什么 JavaScript 可写 属性描述符不禁止任何属性更改 例如 var TheDarkKnight Object create Superhero name value Batman writable false TheDarkKn
  • ngOnChange 不存储 previousValue 属性

    Angular2 RC4 angularfire2 2 0 0 beta 2 在我的子组件中我无法获取changes posX previousValue存储任何东西 父级 html 的片段 inside ngfor loop posX c
  • 将图像从 JQuery 上传到 Node JS

    我需要从我的网站上传图像文件HTML页 但是 我不会使用form标签 因为还有其他form稍后将用于将数据传递到服务器的字段 文本字段 复选框等 我的后端在Node JS 我想要的只是从Node Js结尾 我怎样才能做到这一点 HTML d
  • 使用 OpenCV 查找重叠/复杂的圆

    我想计算红圈半径 图2 我在使用 OpenCV 的 HoughCircles 找到这些圆圈时遇到了麻烦 如图所示 2 我只能使用 HoughCircles 找到中心以黑色显示的小圆圈 original fig 2 由于我知道红色圆圈的中心