opencv案例之统计图像周长、面积

案例背景

照片是来自太空望远镜的星云图像,科学家想知道它的面积和周长


方法步骤

  • 图像二值化
  • 形态学操作
  • 轮廓查找
  • 计算参数

代码

#include <opencv2/opencv.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <iostream>
#include <math.h>

using namespace std;
using namespace cv;

#define PIC_PATH "/work/opencv_pic/"
#define PIC_NAME "case5.png"

int main(void)
{
    Mat src,gray_src;

    //获取完整的图片路径及名称
    string pic = string(PIC_PATH)+string(PIC_NAME);

    //打印图片路径
    cout << "pic path is :"<<pic<<endl;

    //读取图片
    src = imread(pic);

    //判断图片是否存在
    if(src.empty())
    {
        cout<<"pic is not exist!!!!"<<endl;
        return -1;
    }

    //显示图片
    namedWindow("src pic",WINDOW_AUTOSIZE);
    imshow("src pic",src);

    //图片转换为灰度 直接二值化 图片主体存在许多噪点不连续 直接使用开闭操作消除 容易把主体褶皱部分拟合掉
    //测量误差比较大 这里采用高斯模糊解决噪点问题
    cvtColor(src,gray_src,COLOR_BGR2GRAY);
    GaussianBlur(gray_src,gray_src,Size(15,15),0,0);
    imshow("GaussianBlur",gray_src);


    //图片与背景有巨大的反差 先将图片二值化 方便提取主体部分
    //二值化宏采用THRESH_TRIANGLE,未采用THRESH_OTSU是因为THRESH_OTSU效果不理想 噪点较多
    //图片背景色占比较多 直方图属于单峰 采用THRESH_TRIANGLE 效果比较好
    Mat binaryimg;
    threshold(gray_src,binaryimg,0,255,THRESH_BINARY | THRESH_TRIANGLE);
    imshow("binaryimg",binaryimg);

    //轮廓
    vector<vector<Point>> contours;
    findContours(binaryimg,contours,RETR_TREE,CHAIN_APPROX_SIMPLE);

    Mat contouimg = Mat::zeros(src.size(),src.type());
    for(size_t i=0;i<contours.size();i++)
    {
        //绘制最大的轮廓
        Rect rect = boundingRect(contours[i]);
        if(rect.width>src.cols/2 && rect.height >src.rows/2)
        {
            drawContours(contouimg,contours,i,Scalar(0,0,255),1);
            double length = arcLength(contours[i],true);
            double area = contourArea(contours[i]);
            cout << "长度是 "<< length <<endl;
            cout << "面积是 "<< area<<endl;
        }
    }
    imshow("contouimg",contouimg);

    waitKey(0);
    destroyAllWindows();
    return 0;
}

效果演示

在这里插入图片描述

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页