思路:

1、通过形态学操作、阈值处理、距离变换等方法,使得各个轮廓分开

2、计算轮廓数量

 #include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h> using namespace cv;
using namespace std; int main(int argc, char** argv)
{
Mat src = imread("计数.jpg");
//medianBlur(src, src,5);//中值滤波,去除椒盐噪声
imshow("src", src); Mat src_gray,binary; cvtColor(src,src_gray,COLOR_BGR2GRAY); threshold(src_gray,binary,,,THRESH_BINARY|THRESH_TRIANGLE);//颜色单一时,使用THRESH_TRIANGLE比OTSU好
imshow("binary", binary); //形态学操作
Mat kernel = getStructuringElement(MORPH_RECT,Size(,));
dilate(binary, binary, kernel,Point(-,-),); //距离变换
Mat dist;
bitwise_not(binary, binary);//取反
distanceTransform(binary,dist,CV_DIST_L2,);
normalize(dist, dist,,1.0,NORM_MINMAX);
imshow("dist", dist); //阈值化二值分割
//threshold(dist, dist,0.7,1.0,THRESH_BINARY);//对距离进行筛选,去除边缘部分
//normalize(dist, dist, 0, 255, NORM_MINMAX);
Mat dist_8U;
dist.convertTo(dist_8U,CV_8U);
adaptiveThreshold(dist_8U, dist_8U, , ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, , 0.0);//自适应阈值,代替上面的阈值操作
//形态学操作,使得断开部分连接
kernel = getStructuringElement(MORPH_RECT, Size(, ), Point(-, -));
dilate(dist_8U, dist_8U, kernel, Point(-, -),); imshow("dist_8U", dist_8U); // 连通区域计数
vector<vector<Point>> contours;
findContours(dist_8U, contours, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); // draw result
Mat markers = Mat::zeros(src.size(), CV_8UC3);
RNG rng();
for (size_t t = ; t < contours.size(); t++) {
drawContours(markers, contours, static_cast<int>(t), Scalar(rng.uniform(, ), rng.uniform(, ), rng.uniform(, )),
-, , Mat());
}
printf("number of corns : %d", contours.size());
imshow("Final result", markers); waitKey(); return ;
}

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
    Mat src = imread("计数.jpg");
    //medianBlur(src, src,5);//中值滤波,去除椒盐噪声
    imshow("src", src);

Mat src_gray,binary;
    
    cvtColor(src,src_gray,COLOR_BGR2GRAY);
    
    threshold(src_gray,binary,0,255,THRESH_BINARY|THRESH_TRIANGLE);//颜色单一时,使用THRESH_TRIANGLE比OTSU好
    imshow("binary", binary);

//形态学操作
    Mat kernel = getStructuringElement(MORPH_RECT,Size(5,5));
    dilate(binary, binary, kernel,Point(-1,-1),4);

//距离变换
    Mat dist;
    bitwise_not(binary, binary);//取反
    distanceTransform(binary,dist,CV_DIST_L2,3);
    normalize(dist, dist,0,1.0,NORM_MINMAX);
    imshow("dist", dist);

//阈值化二值分割
    //threshold(dist, dist,0.7,1.0,THRESH_BINARY);//对距离进行筛选,去除边缘部分
    //normalize(dist, dist, 0, 255, NORM_MINMAX);
    Mat dist_8U;
    dist.convertTo(dist_8U,CV_8U);
    adaptiveThreshold(dist_8U, dist_8U, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 85, 0.0);//自适应阈值,代替上面的阈值操作
    //形态学操作,使得断开部分连接
    kernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
    dilate(dist_8U, dist_8U, kernel, Point(-1, -1),3);

imshow("dist_8U", dist_8U);

// 连通区域计数
    vector<vector<Point>> contours;
    findContours(dist_8U, contours, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

// draw result
    Mat markers = Mat::zeros(src.size(), CV_8UC3);
    RNG rng(12345);
    for (size_t t = 0; t < contours.size(); t++) {
        drawContours(markers, contours, static_cast<int>(t), Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)),
            -1, 8, Mat());
    }
    printf("number of corns : %d", contours.size());
    imshow("Final result", markers);

waitKey(0);

return 0;
}

opencv——对象计数的更多相关文章

  1. 大数据计算:如何仅用1.5KB内存为十亿对象计数

    大数据计算:如何仅用1.5KB内存为十亿对象计数  Big Data Counting: How To Count A Billion Distinct Objects Using Only 1.5K ...

  2. opencv实践::对象计数

    问题描述 真实案例,农业领域经常需要计算对象个数 或者在其它领域拍照自动计数,可以提供效率,减低成本 解决思路 通过二值分割+形态学处理+距离变换+连通区域计算 #include <opencv ...

  3. opencv——对象提取与测量

    #include <opencv2/opencv.hpp> #include <iostream> #include <math.h> using namespac ...

  4. Opencv轮廓计数(学习)

    #include <iostream>#include <opencv2/opencv.hpp>#include <opencv2/xfeatures2d.hpp> ...

  5. 图像储存容器Mat[OpenCV 笔记11]

    IplImage 与 Mat IplImage是OpenCV1中的图像存储结构体,基于C接口创建.在退出之前必须release,否则就会造成内存泄露.在一些只能使用C语言的嵌入式系统中,不得不使用. ...

  6. opencv::分水岭图像分割

    分水岭分割方法原理 (3种) - 基于浸泡理论的分水岭分割方法 (距离) - 基于连通图的方法 - 基于距离变换的方法 图像形态学操作: - 腐蚀与膨胀 - 开闭操作 分水岭算法运用 - 分割粘连对象 ...

  7. .NET对象与Windows句柄(二):句柄分类和.NET句柄泄露的例子

    上一篇文章介绍了句柄的基本概念,也描述了C#中创建文件句柄的过程.我们已经知道句柄代表Windows内部对象,文件对象就是其中一种,但显然系统中还有更多其它类型的对象.本文将简单介绍Windows对象 ...

  8. 《more effective c++》条款26 限制类对象的个数

    问题: 如何限制类对象的个数?比如1个,10个等等. 方法(1): 将类的构造函数定义为private,那么就无法实例化这个类了.但是如何创建1个对象出来?方法有2种: 1.声明一个友元函数,那么在友 ...

  9. ASP.NET内置对象二

    (1)Respose对象 利用Response对象输出文字信息: protected void Page_Load(object sender, EventArgs e){ string messag ...

随机推荐

  1. Mysql替换两个字段的内容(字符串)

    问题:用一条sql来替换两个字段的内容 表内容:  待优化sql: update student set name=CONCAT(name,dname),dname=SUBSTR(name FROM ...

  2. 继续畅通工程(hdu1879)并查集

    继续畅通工程 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  3. 使用eclipse上Tomcat插件配置域名、端口号、启动时间详解

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7856284.html 邮箱:moyi@moyib ...

  4. 利用LOCK机制来定位前缀劫持者

    一.文章信息 作者:Tongqing Qiu, Lusheng Ji, Dan Pei等 单位:佐治亚理工学院.美国电话电报公司实验室.康奈尔大学等 来源:Conference on Usenix S ...

  5. php pdo对象使用详解: 连接数据库与exec方法

    要使用pdo,首先需要开启pdo扩展,我这里已经开启了mysql的pdo扩展 ghostwu@dev:~$ php -m | grep pdo pdo_mysql ghostwu@dev:~$ 1,连 ...

  6. 常见Java问题

    1.泛型的好处 保护了类型安全 避免了强制类型转化 2.final关键字的作用 final修饰的属性是常量 final修饰的方法不可被重写 final修饰的类不能被继承,如:String 3.静态变量 ...

  7. django-分页paginator

    分页 Django提供了一些类来帮助你管理分页的数据 -- 也就是说,数据被分在不同页面中,并带有“上一页/下一页”标签.这些类位于 django/core/paginator.py 中. 示例 向 ...

  8. onkeyup小练习

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. Linux服务器redhat配置本地yum源

    前面给大家介绍了很多在Linux安装软件的知识,这些软件往往依赖了很多第三方的工具或者软件,如果在Linux服务器有外网的情况,咱们可以通过yum install这样的命令直接去安装这些相关的工具或者 ...

  10. Problem5-Project Euler

    Smallest multiple   2520 is the smallest number that can be divided by each of the numbers from 1 to ...