思路:

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. SORT AGAIN(hdu2523)

    SORT AGAIN Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  2. Java虚拟机 - 类加载机制

    [深入Java虚拟机]之四:类加载机制 类加载过程     类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载.验证.准备.解析.初始化.使用和卸载七个阶段.它们开始的顺序如下 ...

  3. sql连接查询(inner join、full join、left join、 right join)

    sql连接查询(inner join.full join.left join. right join) 一.内连接(inner join) 首先我这有两张表 1.顾客信息表customer 2.消费订 ...

  4. HDU4289(KB11-I 最小割)

    Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  5. BZOJ3884(SummerTrainingDay04-C 欧拉定理)

    上帝与集合的正确用法 根据一些书上的记载,上帝的一次失败的创世经历是这样的: 第一天,  上帝创造了一个世界的基本元素,称做“元”. 第二天,  上帝创造了一个新的元素,称作“α”.“α”被定义为“元 ...

  6. javax.net.ssl.SSLHandshakeException sun.security.validator.ValidatorException PK

    javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building f ...

  7. 从零开始学习html(九)CSS的继承、层叠和特殊性

    一.继承 <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" co ...

  8. drupal 去掉视图中字段默认的HTML标签

    1.格式--设置 去掉复选框 2.具体字段:

  9. php将多个值的数组去除重复元素

    array_unique(array) 只能处理value只有单个的数组. 去除有多个value数组,可以使用如下函数实现: function more_array_unique($arr=array ...

  10. idea加载JSTL库

    被这个错误缠了很长时间,偶然解决.eclipse for EE里导入JSTL没有问题,在JetIdea里就报classnotfound的异常. 解决方案:打包方式fix一下 新建library fil ...