Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何在OpenCV connectedComponents函数之后分割对象

如何在OpenCV connectedComponents函数之后分割对象
EN

Stack Overflow用户
提问于 2015-10-07 07:56:06
回答 3查看 4.3K关注 0票数 2

我得到了一个带有connectedComponents函数C++ OpenCV的标签,如图中所示:

这是ccLabels变量的输出,它是一个与原始图像大小相同的cv::Mat

所以我要做的是:

  1. 计算每个数字的出现情况,并选择那些发生的次数超过N次数,这是“大”的。
  2. 分割“大”组件的区域,然后计算该区域内的4和0的数量。

我的最终目标是计算图像中的洞数,因此我的目标是从(number of 0's / number of 4's)中推断出洞数。这可能不是最漂亮的方式,但图像是非常均匀的大小和照明,所以它将满足我的需要。

但是我对OpenCV并不熟悉,我不知道如何完成这个任务。

以下是我迄今所做的工作:

代码语言:javascript
运行
AI代码解释
复制
cv::Mat1b outImg;
cv::threshold(grayImg, outImg, 150, 255, 0); // Thresholded -binary- image
cv::Mat ccLabels;
cv::connectedComponents(outImg, ccLabels); // Each non-zero pixel is labeled with their connectedComponent ID's
// write the labels to file:
std::ofstream myfile;
    myfile.open("ccLabels.txt");
    cv::Size s = ccLabels.size();
    myfile << "Size: " << s.height << " , " << s.width <<"\n";
    for (int r1 = 0; r1 < s.height; r1++) {
        for (int c1 = 0; c1 < s.height; c1++) {
            myfile << ccLabels.at<int>(r1,c1);
        }
        myfile << "\n";
    }
    myfile.close();

因为我知道如何在矩阵中迭代,所以计数数字应该是可以的,但是首先我必须分离(消除/忽略)“背景”像素,它们是之外的0's 连接的组件。那么数数应该很容易。

我如何分割这些“大”组件?也许可以获得一个掩码,并且只考虑mask(x,y) = 1所在的像素

谢谢你的帮助!

编辑

这是被分割的图像:

这就是我在Canny边缘检测之后得到的结果:

这是实际图像(阈值):

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-10-07 10:12:31

这里有一个简单的程序,从你的阈值图像开始,找到骰子上的数字。

  1. 寻找外部轮廓
  2. 对于每个等高线
    • 最后丢弃小水珠
    • 画满面具
    • 使用和和XOR隔离内部孔
    • 再找一次轮廓
    • 数等高线

结果:

代码语言:javascript
运行
AI代码解释
复制
Number: 5
Number: 2

图片:

代码:

代码语言:javascript
运行
AI代码解释
复制
#include <opencv2\opencv.hpp>
#include <iostream>
#include <vector>
using namespace std;
using namespace cv;

int main(void)
{
    // Grayscale image
    Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);

    // Minimum area of the contour
    double minContourArea = 10;

    // Prepare outpot
    Mat3b result;
    cvtColor(img, result, COLOR_GRAY2BGR);

    // Find contours
    vector<vector<Point>> contours;
    findContours(img.clone(), contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

    for (int i = 0; i < contours.size(); ++i)
    {
        // Check area
        if (contourArea(contours[i]) < minContourArea) continue;

        // Black mask
        Mat1b mask(img.rows, img.cols, uchar(0));
        // Draw filled contour
        drawContours(mask, contours, i, Scalar(255), CV_FILLED);

        mask = (mask & img) ^ mask;

        vector<vector<Point>> cntrs;
        findContours(mask, cntrs, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

        cout << "Number: " << cntrs.size() << endl;

        // Just for showing results
        drawContours(result, cntrs, -1, Scalar(0,0,255), CV_FILLED);
    }

    imshow("Result", result);
    waitKey();

    return 0;
}
票数 3
EN

Stack Overflow用户

发布于 2015-10-07 08:22:37

更简单的方法是findContours方法。您找到内部轮廓并计算它们的面积(因为内部轮廓将是洞)并相应地处理这些信息。

票数 -1
EN

Stack Overflow用户

发布于 2015-10-07 09:44:00

要解决您的第一个问题,请考虑在values.Count中有一组值,即出现的每一个数字。

代码语言:javascript
运行
AI代码解释
复制
 int m=0;
    for(int n=0;n<256;n++)
    {
        int c=0;
        for(int q=0;q<values.size();q++)
        {
            if(n==values[q])
            {
                //int c;
            c++;
            m++;
            }
        }

        cout<<n<<"= "<< c<<endl;
    }
    cout<<"Total number of elements "<< m<<endl;

要解决第二个问题,使用find等值线在图像中找到最大的轮廓,在其周围画出包围矩形,然后裁剪它。再次使用上面的代码来计数像素值"4“和"0”。您可以在这里找到它的链接,https://stackoverflow.com/a/32998275/3853072

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32996963

复制
相关文章
教程 | OpenCV Grabcut对象分割
Grabcut是基于图割(graph cut)实现的图像分割算法,它需要用户输入一个bounding box作为分割目标位置,实现对目标与背景的分离/分割,这个跟KMeans与MeanShift等图像分割方法有很大的不同,但是Grabcut分割速度快,效果好,支持交互操作,因此在很多APP图像分割/背景虚化的软件中可以看到其身影。
OpenCV学堂
2019/03/07
4K0
如何使用C++和OpenCV库将彩色图像按连通域进行区分?
在计算机视觉和图像处理中,将彩色图像按照连通域进行区分是一种常见的操作。通过将图像转化为灰度图像,然后使用图像分割和连通域分析算法,我们可以识别出图像中的不同物体或区域,并对其进行进一步的处理和分析。本文将详细介绍如何使用C++和OpenCV库将彩色图像按连通域进行区分。
网络技术联盟站
2023/09/04
6080
如何使用C++和OpenCV库将彩色图像按连通域进行区分?
Python opencv图像处理基础总结(七) 基于分水岭算法的图像分割
文章目录 一、 原理 1. 分水岭算法原理 2. 距离变换 3. opencv有关函数的用法 二、基于距离的分水岭分割流程 三、python代码实现 一、 原理 1. 分水岭算法原理 任何一副灰度图像都可以被看成拓扑平面,灰度值高的区域可以被看成是山峰,灰度值低的区域可以被看成是山谷。我们向每一个山谷中灌不同颜色的水。随着水的位的升高,不同山谷的水就会相遇汇合,为了防止不同山谷的水汇合,我们需要在水汇合的地方构建起堤坝。不停地灌水,不停地构建堤坝知道所有的山峰都被水淹没。我们构建好的堤坝就是对图像的分割,这
叶庭云
2022/05/09
3.1K0
Python opencv图像处理基础总结(七) 基于分水岭算法的图像分割
OpenCV: 分水岭算法的图像分割及Grabcut算法交互式前景提取
任何灰度图像都可以看作是一个地形表面,其中高强度的像素表示山峰,低强度表示山谷。可以用不同颜色的水(标签)填充每个孤立的山谷(局部最小值)。随着水位的上升,根据附近的山峰(坡度),来自不同山谷的水明显会开始合并,颜色也不同。为了避免这种情况,要在水融合的地方建造屏障。继续填满水,建造障碍,直到所有的山峰都在水下。然后创建的屏障将返回分割结果。这就是Watershed(分水岭算法)背后的“思想”。
用户3578099
2023/09/01
1.1K0
OpenCV: 分水岭算法的图像分割及Grabcut算法交互式前景提取
OpenCV车牌文字分割
基于像素直方图,实现字符分割:首先对图片进行二值化处理,统计水平方向和竖直方向上各行各列的黑色像素的个数,根据像素的特点确定分割位置,进而完成字符分割。
AnieaLanie
2021/12/24
1.3K0
【OpenCV 4开发详解】图像连通域分析
图像的连通域是指图像中具有相同像素值并且位置相邻的像素组成的区域,连通域分析是指在图像中寻找出彼此互相独立的连通域并将其标记出来。提取图像中不同的连通域是图像处理中较为常用的方法,例如在车牌识别、文字识别、目标检测等领域对感兴趣区域分割与识别。一般情况下,一个连通域内只包含一个像素值,因此为了防止像素值波动对提取不同连通域的影响,连通域分析常处理的是二值化后的图像。
小白学视觉
2020/02/12
6.4K0
【OpenCV 4开发详解】图像连通域分析
函数cv2.connectedComponents的实际应用代码分享
plt.xlabel('Height'), plt.ylabel('Width')
好派笔记
2022/06/08
8300
C++ OpenCV图像分割之GrabCut分割
在OpenCV中的图像分割中GrabCut分割算法,该算法可以方便的分割出前景图像,操作简单,而且分割的效果很好。在前我们刚用学了OpenCV中的鼠标回调函数,也是为了这章用GrabCut做基础。
Vaccae
2019/07/24
2.2K0
cv2.error: OpenCV(4.1.0) C:\projects\opencv-python\opencv\modules\imgproc\src\se
sure_bg = cv.dilate(waterimg, kernel, iterations=3)# 确定背景
用户7886150
2021/01/16
1.5K0
基于 OpenCV 的图像分割
https://github.com/kiteco/kite-python-blog-post-code/tree/master/image-segmentation
小白学视觉
2020/09/22
1.3K0
基于 OpenCV 的图像分割
基于OpenCV的图像分割
输入图像 const int N = 3; //聚类个数 // const int N1 = (int)sqrt((double)N); //每一类用一种颜色 // const Scalar colors[] = // { // Scalar(0,0,255), Scalar(0,255,0), // Scalar(0,255,255),Scalar(255,255,0) // }; Vec3b colorTab[] =
用户9831583
2022/06/16
5230
基于OpenCV的图像分割
使用 OpenCV 进行图像分割
图像分割是将数字图像划分互不相交的区域的过程,它可以降低图像的复杂性,从而使分析图像变得更简单
小白学视觉
2022/02/09
2.1K0
使用 OpenCV 进行图像分割
使用OpenCV进行颜色分割
在滤波、变换、缩放等任务中,图像分割具有重要的意义。图像分割是将不同的对象划分为不同的部分,并将这些区域以明显的颜色或者记号标记出来。图像分割是使用轮廓、边界框等概念进行其他高级计算机视觉任务(例如对象分类和对象检测)的基础。良好的图像分割为我们后续的图像分类以及检测奠定了基础。
小白学视觉
2020/07/09
2.6K0
使用OpenCV进行颜色分割
OpenCV 轮廓 —— 轮廓查找
取值 含义 cv2.CHAIN_APPROX_NONE 存储了所有的轮廓点。也就是说,等高线的任意2个后续点(x1,y1)和(x2,y2)将是水平、垂直或对角线邻居,即 max (abs (x1-x2),abs (y2-y1)) = 1。 cv2.CHAIN_APPROX_SIMPLE 压缩水平、垂直和对角线段,只留下它们的端点。例如,一个直立的矩形轮廓用 4 个点进行编码。 cv2.CHAIN_APPROX_TC89_L1 运用了 Teh-Chin 连锁近似演算法的一种 cv2.CHAIN_APPROX_TC89_KCOS 运用了 Teh-Chin 连锁近似演算法的一种
为为为什么
2022/08/09
3.2K0
OpenCV 轮廓 —— 轮廓查找
使用OpenCV进行颜色分割
在滤波、变换、缩放等任务中,图像分割具有重要的意义。图像分割是将不同的对象划分为不同的部分,并将这些区域以明显的颜色或者记号标记出来。图像分割是使用轮廓、边界框等概念进行其他高级计算机视觉任务(例如对象分类和对象检测)的基础。良好的图像分割为我们后续的图像分类以及检测奠定了基础。
AI算法与图像处理
2020/07/09
3K0
使用OpenCV进行颜色分割
OpenCV 深度估计与分割
使用深度摄像头的数据来识别前景区域和背景区域,首先要有一个深度摄像头,比如微软的Kinect,英特尔的realsense。
小白学视觉
2022/09/28
6830
图解Spark Graphx基于connectedComponents函数实现连通图底层原理
按照官网的介绍,NebulaGraph Algorithm是一款基于GraphX 的 Spark 应用程序,通过提交 Spark 任务的形式,使用完整的算法工具对 NebulaGraph 数据库中的数据执行图计算。
朱季谦
2023/09/04
4950
图解Spark Graphx基于connectedComponents函数实现连通图底层原理
OpenCV源码系列|背景分割
应用场景:静态摄像头统计路过的行人数量,交通摄像头提取路过的交通车辆等。 技术核心:从静态的背景中把动态的物体提取并分割。 输入视频:打开摄像头,没有物体进入(仅仅做的截图) 输出视频:手机突然进入摄像头范围内 代码实现: #include "opencv2/core.hpp" #include "opencv2/imgproc.hpp" #include "opencv2/video.hpp" #include "opencv2/videoio.hpp" #include "opencv2
用户9831583
2022/06/16
2880
OpenCV源码系列|背景分割
OpenCV 图像分析之 —— 分割
图像分割是个很大的话题,这里,我们重点研究 OpenCV 中的几种专门实现分割方法的技术实现或者后面要用到的形态学策略。
为为为什么
2022/08/09
2.6K0
OpenCV 图像分析之 —— 分割
点击加载更多

相似问题

OpenCV for Python - AttributeError:“OpenCV”对象没有属性“connectedComponents”

10

如何使用OpenCV ConnectedComponents获取图像

10

在Python OpenCV中查找connectedComponents的颜色

20

opencv python connectedComponents选择每个标签的组件

15

connectedComponents在OpenCV2中的统计

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文