#include <opencv2/opencv.hpp>
#include <iostream> using namespace cv;
using namespace std;
RNG rng(12345); void ccl_stats_demo(Mat& image); int main(int argc, char** argv)
{
Mat src = imread("f:/images/qq/20200215213837.png");
if (src.empty())
{
printf("Could not find the image!\n");
return -1;
} namedWindow("input", WINDOW_AUTOSIZE);
imshow("input", src); // 做一个高斯模糊,消除一些细微的东西
GaussianBlur(src, src, Size(3, 3), 0);
GaussianBlur(src, src, Size(3, 3), 0); Mat gray, binary;
cvtColor(src, gray, COLOR_BGR2GRAY);
imshow("gray", gray); threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
imshow("binary", binary); // 获取联通组件,没有附加信息的
/*
Mat labels = Mat::zeros(binary.size(), CV_32S);
int num_labels = connectedComponents(binary, labels, 8, CV_32S);
printf("total labels: %d\n", num_labels-1);
vector<Vec3b> colorTable(num_labels);
// background color
colorTable[0] = Vec3b(0, 0, 0);
for (int i = 1; i < num_labels; i++) {
colorTable[i] = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
} Mat result = Mat::zeros(src.size(), src.type());
int w = result.cols;
int h = result.rows;
for (int row = 0; row < h; row++) {
for (int col = 0; col < w; col++) {
int label = labels.at<int>(row, col);
result.at<Vec3b>(row, col) = colorTable[label];
}
}
putText(result,
format("number: %d", num_labels - 1),
Point(50, 50), FONT_HERSHEY_PLAIN, 1.0,
Scalar(0, 255, 0), 1);
imshow("CCL demo", result);
*/ // 获取联通组件,有附加信息
ccl_stats_demo(binary); waitKey(0);
destroyAllWindows(); return 0;
} void ccl_stats_demo(Mat& image) {
Mat labels = Mat::zeros(image.size(), CV_32S);
Mat stats, centroids;
int num_labels = connectedComponentsWithStats(image, labels, stats, centroids, 8, CV_32S, CCL_DEFAULT);
printf("total labels: %d\n", num_labels - 1);
vector<Vec3b> colorTable(num_labels);
// background color
colorTable[0] = Vec3b(0, 0, 0);
for (int i = 1; i < num_labels; i++) {
colorTable[i] = Vec3b(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
} // 注意这里的result的类型
Mat result = Mat::zeros(image.size(), CV_8UC3);
int w = result.cols;
int h = result.rows;
for (int row = 0; row < h; row++) {
for (int col = 0; col < w; col++) {
int label = labels.at<int>(row, col);
result.at<Vec3b>(row, col) = colorTable[label];
}
}
for (int i = 1; i < num_labels; i++) {
// 获取中心位置
int cx = centroids.at<double>(i, 0);
int cy = centroids.at<double>(i, 1);
// 获取外接矩形 和面积
int x = stats.at<int>(i, CC_STAT_LEFT);
int y = stats.at<int>(i, CC_STAT_TOP);
int width = stats.at<int>(i, CC_STAT_WIDTH);
int height = stats.at<int>(i, CC_STAT_HEIGHT);
// 这个面积的单位是像素
int area = stats.at<int>(i, CC_STAT_AREA);
// 绘制中心位置
circle(result, Point(cx, cy), 3, Scalar(0, 0, 255), 2, 8, 0);
// 绘制外接矩形
Rect box(x, y, width, height);
rectangle(result, box, Scalar(0, 255, 0), 2, 8, 0);
putText(result,
format("%d", area),
Point(x, y), FONT_HERSHEY_PLAIN, 1.0,
Scalar(0, 255, 0), 1);
} putText(result,
format("number: %d", num_labels - 1),
Point(50, 50), FONT_HERSHEY_PLAIN, 1.0,
Scalar(0, 255, 0), 1);
imshow("CCL demo", result);
}

opencv:联通组件扫描的更多相关文章

  1. Spring - 基于注解的组件扫描

    关于Spring的书籍都会花很大篇幅来讲解Spring如何注入各种bean的问题,非常令人头疼,自己在工作中还从来没有用到过. 所以就要跳过那些篇章,直接学习基于注解的组件扫描. 发现spring2是 ...

  2. Spring学习笔记之 Spring IOC容器(二) 之注入参数值,自动组件扫描方式,控制Bean实例化方式,使用注解方式

     本节主要内容:    1. 给MessageBean注入参数值    2. 测试Spring自动组件扫描方式    3. 如何控制ExampleBean实例化方式    4. 使用注解方式重构Jdb ...

  3. Spring装配bean--01组件扫描和自动装配

    Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系 Spring提供了三种主要的装配机制: 在XML中进行显式配置 在Java中进行显式配置 隐式的bean发现机制和自动装 ...

  4. Spring装配Bean之组件扫描和自动装配

    Spring从两个角度来实现自动化装配: 组件扫描:Spring会自动发现应用上下文中所创建的bean. 自动装配:Spring自动满足bean之间的依赖. 案例:音响系统的组件.首先为CD创建Com ...

  5. Unit02: 参数值注入 、 基于注解的组件扫描

    Unit02: 参数值注入 . 基于注解的组件扫描 (4)IOC (Inversion Of Controll 控制反转) 什么是IOC? 对象之间的依赖关系由容器来建立. 什么是DI? (Depen ...

  6. Spring注解的使用和组件扫描

    非常重要] 组件扫描(Component-Scan) 通过配置组件扫描,可以使得spring自动扫描package,而不必在spring的配置文件中逐一声明各个<bean> 在配置组件扫描 ...

  7. 1 spring如何通过组件扫描和自动装配实现自动化的配置

    1 首先将spring依赖的包全部导入 2 建立测试接口 public interface CompactDisc { void play(); } 3 具体的类实现接口 import org.spr ...

  8. Spring IOC基础回顾 — 组件扫描和装配

    目录 注解形式配置应用IOC 1. 组件自动扫描 2. 组件依赖:为bean添加注解,实现自动注入 3. Spring IOC应用小结 注解形式配置应用IOC 在类定义.方法定义.成员变量定义前使用, ...

  9. 装配SpringBean(四)--注解装配之组件扫描

    前两篇文章我总结了通过XML方式装配bean的实现方式,虽然比较简单,但是需要配置很多,很多时候我们都会使用注解进行装配.使用注解的方式可以减少XML的配置,既能实现XML的功能,还提供了自动装配功能 ...

随机推荐

  1. 本机添加多IP绑定网站

    查询IP 显示为1个IP 点击更改适配器 点击高级 进行添加IP 点击添加 ipconfig 查看效果 注~!:在IIS中可以在这里添加多IP然后绑定

  2. early-stopping的使用

    early-stopping的使用 待办 https://blog.csdn.net/qq_37430422/article/details/103638681 github对应类导入,直接放在项目更 ...

  3. 项目部署到tomcat,验证部署成功

    1.假设你已经知道打war包放上去了tomcat 下的webapps下 2. bin->启动startup.bat 3.浏览器中启动 http://ip:port    这个port是tomca ...

  4. 静态区间第k小 - 整体二分

    蒟蒻终于学会整体二分啦! 思路 实现 丑陋无比的代码 #include <bits/stdc++.h> using namespace std; const int N = 200005; ...

  5. 番外:Oracle 中关于 Control File 的备份说明

    番外系列说明:该系列所有文章都将作为独立篇章进行知识点讲解,是对其他系列博文进行的补充说明,来自于博客园AskScuti. 主题:关于 Control File 控制文件备份的说明 内容预览:本篇涉及 ...

  6. 图的最短路径算法-- Floyd算法

    Floyd算法求的是图的任意两点之间的最短距离 下面是Floyd算法的代码实现模板: ; ; // maxv为最大顶点数 int n, m; // n 为顶点数,m为边数 int dis[maxv][ ...

  7. 题解【洛谷P1725】琪露诺

    题面 典型的单调队列优化\(\text{DP}\)题. 不难想到设\(dp_i\)表示以\(i\)结尾能得到的最大冰冻指数. 这样设的转移方程也很简单:\(dp_i=\max\left\{ dp_j+ ...

  8. shiro认证和授权

    一.shiro基础概念 Authentication:身份认证 / 登录,验证用户是不是拥有相应的身份: Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限:即判断用户 ...

  9. K3/Cloud树形单据体的rowId赋值

    RowId是树形单据体独有的,同一单据体中不能重复,用如下语句取. System.Guid.NewGuid().ToString() 同时FGROUP也需要重新设置,值可以和FSeq一样.

  10. [BZOJ4310] 跳蚤 - 后缀数组,二分,ST表

    [BZOJ4310] 跳蚤 Description 首先,他会把串分成不超过 \(k\) 个子串,然后对于每个子串 \(S\) ,他会从 \(S\) 的所有子串中选择字典序最大的那一个,并在选出来的 ...