小案例:使用OpenCV数一数图像中硬币的个数

一、概述

  案例:给出一张堆满硬币的图像,找出这张图像中硬币的总个数

  实现步骤:

  1.加载原图

  2.灰度化图像

  3.进行二值分割(自动预值)的出二值图像

  4.进行形态学开操作去掉黑色噪声

  5.执行距离变换

  6.执行阀值二值化(分离各个硬币)

  7.执行边缘检测

  8.执行轮廓发现(轮廓的个数就是硬币的个数)

  9.显示最终图片并输出硬币个数

二、代码演示

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_OTSU);
    imshow("threshold",gray);
    //执行形态学开操作消除图像中的造点
    Mat kernel = getStructuringElement(MORPH_RECT,Size(3,3));
    morphologyEx(gray,gray,MORPH_OPEN,kernel,Point(-1,-1),2);//2代表连续开操作两次
    imshow("morphologyEx",gray);
    //    dilate(gray,gray,kernel,Point(-1,-1),3);
    //进行距离变换
    distanceImage = Mat(gray.size(),CV_32FC1);
    distanceTransform(gray,distanceImage,DIST_L2,5);
    normalize(distanceImage,distanceImage,0,1,NORM_MINMAX);
    imshow("distanceTransForm",distanceImage);
    //局部二值化
    //    normalize(distanceImage,distanceImage,0,255,NORM_MINMAX);
    //    adaptiveThreshold(MorphImg, MorphImg, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 85, 0.0);//使
    threshold(distanceImage,distanceImage,0.6,1,THRESH_BINARY);
    imshow("thre",distanceImage);
    //边缘检测
    normalize(distanceImage,distanceImage,0,255,NORM_MINMAX);
    Mat mat8;
    distanceImage.convertTo(mat8,CV_8UC1);
    imshow("result1",mat8);
    Canny(mat8,mat8,0,255);

    //执行轮廓发现
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;//拓扑结构
    Mat myResult = Mat::zeros(mat8.size(),CV_8UC3);
    findContours(mat8,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:48  飘杨......  阅读(680)  评论(0编辑  收藏  举报