• 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;
    }


  • 相关阅读:
    vsftpd下错误之:500 OOPS
    material mem
    如何查看core文件
    java 开发工具使用
    Java计算几何图形的面积
    Java实现经理与员工的差异
    Java适配器模式的简单应用
    Java实现策略模式的简单应用
    Java单例模式的应用
    Java求解汉诺塔问题
  • 原文地址:https://www.cnblogs.com/long5683/p/9750219.html
Copyright © 2020-2023  润新知