opencv——对象计数

Posted long5683

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了opencv——对象计数相关的知识,希望对你有一定的参考价值。

技术分享图片

 思路:

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

2、计算轮廓数量

 

 1 #include <opencv2/opencv.hpp>
 2 #include <iostream>
 3 #include <math.h>
 4 
 5 using namespace cv;
 6 using namespace std;
 7 
 8 
 9 int main(int argc, char** argv)
10 {
11     Mat src = imread("计数.jpg");
12     //medianBlur(src, src,5);//中值滤波,去除椒盐噪声
13     imshow("src", src);
14 
15     Mat src_gray,binary;
16     
17     cvtColor(src,src_gray,COLOR_BGR2GRAY);
18     
19     threshold(src_gray,binary,0,255,THRESH_BINARY|THRESH_TRIANGLE);//颜色单一时,使用THRESH_TRIANGLE比OTSU好
20     imshow("binary", binary);
21 
22     //形态学操作
23     Mat kernel = getStructuringElement(MORPH_RECT,Size(5,5));
24     dilate(binary, binary, kernel,Point(-1,-1),4);
25 
26     //距离变换
27     Mat dist;
28     bitwise_not(binary, binary);//取反
29     distanceTransform(binary,dist,CV_DIST_L2,3);
30     normalize(dist, dist,0,1.0,NORM_MINMAX);
31     imshow("dist", dist);
32 
33     //阈值化二值分割
34     //threshold(dist, dist,0.7,1.0,THRESH_BINARY);//对距离进行筛选,去除边缘部分
35     //normalize(dist, dist, 0, 255, NORM_MINMAX);
36     Mat dist_8U;
37     dist.convertTo(dist_8U,CV_8U);
38     adaptiveThreshold(dist_8U, dist_8U, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 85, 0.0);//自适应阈值,代替上面的阈值操作
39     //形态学操作,使得断开部分连接
40     kernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
41     dilate(dist_8U, dist_8U, kernel, Point(-1, -1),3);
42 
43     imshow("dist_8U", dist_8U);
44 
45     // 连通区域计数
46     vector<vector<Point>> contours;
47     findContours(dist_8U, contours, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
48 
49     // draw result
50     Mat markers = Mat::zeros(src.size(), CV_8UC3);
51     RNG rng(12345);
52     for (size_t t = 0; t < contours.size(); t++) {
53         drawContours(markers, contours, static_cast<int>(t), Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)),
54             -1, 8, Mat());
55     }
56     printf("number of corns : %d", contours.size());
57     imshow("Final result", markers);
58 
59     waitKey(0);
60 
61     return 0;
62 }

 

#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——对象计数的主要内容,如果未能解决你的问题,请参考以下文章

Opencv 对象跟踪和计数在视频帧中通过 ROI 的对象

OpenCV C++案例实战九《对象计数》

在 Python 多处理进程中运行较慢的 OpenCV 代码片段

web代码片段

Opencv中对象检测的重叠

OpenCV + CPP 系列(卌六)目标检测与计数