opencv案例之对象提取

案例场景

将图片中的某个元素,提取。这里在黑白图中扣取圆圈部分


实现方法


代码实现


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

using namespace std;
using namespace cv;

#define PIC_PATH "/work/opencv_pic/"
#define PIC_NAME "case3.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;
    }

    imshow("原图显示",src);
    cvtColor(src,gray_src,COLOR_BGR2GRAY);


    //图像二值化
    threshold(gray_src,gray_src,0,255,THRESH_BINARY | THRESH_OTSU);

    //形态学开闭操作 去除噪点、不连续区域等干扰信息 方便以后特征提取
    Mat kernel = getStructuringElement(MORPH_RECT,Size(3,3),Point(-1,-1));

    //闭操作 消除小黑点 使某些不连续区域连续起来
    morphologyEx(gray_src,gray_src,MORPH_CLOSE,kernel,Point(-1,-1));
    //开操作 消除小白点 使某些白色噪点消失 画面更纯净
    morphologyEx(gray_src,gray_src,MORPH_OPEN,kernel,Point(-1,-1));
    //获得纯净的 分区明显的特征图
    imshow("形态学处理",gray_src);

    //轮廓查找
    vector<vector<Point>> contours;  //轮廓集合
    vector<Vec4i> hierarchy;   //轮廓索引关系
    findContours(gray_src,contours,hierarchy,RETR_TREE,CHAIN_APPROX_SIMPLE,Point(0,0));

    //轮廓绘制
    Mat contourimg = Mat::zeros(src.size(),CV_8UC3);
    Mat circleimg = src.clone();
    for(size_t i=0;i<contours.size();i++)
    {
        //如果有干扰轮廓出现 通过面积过滤 过滤面积较小的轮廓(这里我们的目标轮廓是比较大的)
        double area = contourArea(contours[i]);
        if(area < 50)
            continue;

        //通过横纵比滤除干扰轮廓 检测的目标圆接近1:1
        Rect rect = boundingRect(contours[i]);
        float width = rect.width;
        float hight = rect.height;
        float calc_val = width/hight;

        if(calc_val > 0.9 && calc_val <1.1)
        {
            drawContours(contourimg,contours,i,Scalar(0,0,255),2,8,Mat(),0,Point());
            imshow("筛选后轮廓绘制",contourimg);

            //计算圆心位置
            int x = rect.x + rect.width /2;
            int y = rect.y + rect.height /2;
            Point cc = Point(x,y);

            //计算半径
            double r = arcLength(contours[i],true)/(2*CV_PI);
            cout << "半径" << r << endl;

            //绘制圆形
            circle(circleimg ,cc,cvRound(r),Scalar(0,0,255),2,8,0);
            imshow("原图目标标定",circleimg);

        }
    }

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

效果演示

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值