小案例:使用OpenCV数一数玉米粒的个数

一、概述

  案例:给出一张玉米图片数一数有多少玉米粒(ps:玉米粒之间有相互压住的情况)

  实现步骤:

    1.输入原图

    2.灰度图像

    3.二值化(使用自动预值),黑白图

    4.使用心态学开操作进行降噪声

    5.对图像进行腐蚀,对白色区域进行尽可能隔离,为下一步距离变换做准备

    6.执行距离变换

    7.进行局部二值化(将玉米粒隔离开)

    8.进行膨胀操作消除黑色噪点

    9.执行边缘检测

    10.执行轮廓发现

    11.绘制轮廓并得出轮廓个数,轮廓的个数就是玉米粒的个数。

    12.结束

二、代码示例

src = imread(filePath);
    if(src.empty()){
        cout << "图像数据为空"<<endl;
        return;
    }
    imshow("src",src);
    blur(src,src,Size(3,3),Point(-1,-1));//均值模糊去除一些噪声
    cvtColor(src,gray,COLOR_BGR2GRAY);//转为灰度图像
    //对图像进行二值分割,使用自动预值的方法
    threshold(gray,gray,0,255,THRESH_BINARY_INV|THRESH_TRIANGLE);
    imshow("threshold",gray);
    //执行形态学开操作消除图像中的噪声点
    Mat kernel = getStructuringElement(MORPH_RECT,Size(5,5));
    morphologyEx(gray,gray,MORPH_OPEN,kernel,Point(-1,-1),3);//2代表连续开操作两次
    imshow("morphologyEx",gray);
    //对图像进行腐蚀,为下一步距离变换做准备
    erode(gray,gray,kernel,Point(-1,-1),3);
    imshow("erode",gray);
    //进行距离变换
    distanceImage = Mat(gray.size(),CV_32FC1);
    distanceTransform(gray,distanceImage,DIST_L2,3);
    normalize(distanceImage,distanceImage,0,1,NORM_MINMAX);//归一化处理
    imshow("distanceTransForm",distanceImage);
    //局部二值化
    Mat dist_8u;
    distanceImage.convertTo(dist_8u,CV_8U);
    adaptiveThreshold(dist_8u,dist_8u,255,ADAPTIVE_THRESH_GAUSSIAN_C,THRESH_BINARY,85,0);
    imshow("thre",dist_8u);
    kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
    //进一步膨胀,尽可能的消除黑色噪声点
    dilate(dist_8u, dist_8u, kernel, Point(-1, -1), 5);
    imshow("dist-binary", dist_8u);
    //边缘检测
    Canny(dist_8u,dist_8u,0,255);
    //执行轮廓发现
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;//拓扑结构
    Mat myResult = Mat::zeros(dist_8u.size(),CV_8UC3);
    findContours(dist_8u,contours,hierarchy,RETR_EXTERNAL,CHAIN_APPROX_SIMPLE);
    RNG rng(12345);
    for(size_t i =0;i<contours.size();i++){
        //绘制轮廓
        drawContours(myResult,contours,i,Scalar(rng.uniform(0,255),rng.uniform(0,255),rng.uniform(0,255)),-1);
    }
    //轮廓计数
    cout<< "number of:"<<contours.size()<<endl;
    imshow("result",myResult);

 

三、图片演示

 

posted on 2022-03-09 11:43  飘杨......  阅读(427)  评论(0编辑  收藏  举报