OpenCV C++案例实战二十五《形状识别》

OpenCV C++案例实战二十五《形状识别》


前言

本案例通过使用OpenCV中的approxPolyDP进行多边形近似,进而进行基础形状识别(圆、三角形、矩形、星形…)。下面就一起来看看具体是如何实现的吧。

一、图像预处理

原图如图所示:

请添加图片描述
首先第一步先进行图像预处理,得到二值图像。

	Mat gray;
	cvtColor(src, gray, COLOR_BGR2GRAY);
Mat gaussian<span class="token punctuation">;</span>
<span class="token function">GaussianBlur</span><span class="token punctuation">(</span>gray<span class="token punctuation">,</span> gaussian<span class="token punctuation">,</span> <span class="token function">Size</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

Mat thresh<span class="token punctuation">;</span>
<span class="token function">threshold</span><span class="token punctuation">(</span>gaussian<span class="token punctuation">,</span> thresh<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">,</span> THRESH_BINARY_INV <span class="token operator">|</span> THRESH_OTSU<span class="token punctuation">)</span><span class="token punctuation">;</span>

    请添加图片描述
    结果如图所示。接下来,需要对此二值图像进行轮廓提取,进而识别物体形状。

    二、形状识别

    本案例使用approxPolyDP进行形状识别,关于approxPolyDP OpenCV给出的定义是:

    void approxPolyDP(InputArray curve, OutputArray approxCurve, double epsilon, bool closed);
    curve:表示输入轮廓点集,可以是 vector 或 Mat 类型。
    approxCurve:多边形逼近结果,存储在approxCurve数组中。curve和approxCurve应该属于同一类型。
    epsilon:表示逼近准确度,你允许在原多边形和最终拟合的多边形之间存在的最大偏差。一般以其周长的百分比进行近似。
    closed:指明curve中的一系列点是否是一个闭合的多边形。若设为true,则认为曲线是闭合的。

    我们通过统计多边形的“边”数来识别物体形状

    三、源码

    #include<iostream>
    #include<opencv2/opencv.hpp>
    using namespace std;
    using namespace cv;
    

    //基础几何形状识别
    bool Pattern_Recognition(Mat& src)
    {
    //图像预处理
    Mat gray;
    cvtColor(src, gray, COLOR_BGR2GRAY);

    Mat gaussian;
    GaussianBlur(gray, gaussian, Size(3, 3), 0);

    Mat thresh;
    threshold(gaussian, thresh, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);

    //轮廓查找
    vector<vector<Point>>contours;//轮廓点集
    findContours(thresh, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    vector<vector<Point>>conPoly(contours.size());//多边形逼近结果,与轮廓一一对应

    for (int i = 0; i < contours.size(); i++)
    {
    double area = contourArea(contours[i]); //轮廓面积

    if (area > 1000)
    {
    Rect rect = boundingRect(contours[i]);//外界矩形

    double ratio = double(rect.width) / double(rect.height);//长宽比

    double peri = arcLength(contours[i], true);//周长

    approxPolyDP(contours[i], conPoly[i], 0.02 * peri, true);//多边形近似

    int objSize = conPoly[i].size();//折线数–通过判断轮廓有几条边来识别图形

    string objName;
    Scalar color;
    if (objSize 3)
    {
    objName = “Triangle”;//三角形
    color = Scalar(0, 0, 255);
    }
    if (objSize 4)
    {
    //通过长宽比判断正方形/长方形
    if (ratio > 0.99 && ratio < 1.01)
    {
    objName = “Square”;//正方形
    color = Scalar(0, 255, 255);
    }
    else
    {
    objName = “Rectangle”;//长方形
    color = Scalar(0, 255, 0);
    }
    }
    if (objSize 8)
    {
    objName = “Circle”;//圆形
    color = Scalar(255, 255, 0);
    }
    if (objSize 10)
    {
    objName = “Star”;//星形
    color = Scalar(255, 0, 255);
    }

    //效果绘制
    rectangle(src, rect, color, 2);
    putText(src, objName, rect.tl(), FONT_HERSHEY_SIMPLEX, 1, color, 2);
    }
    }

    return true;
    }

    int main()
    {
    Mat src = imread(“src.jpeg”);
    if (src.empty())
    {
    cout << “No Image!” << endl;
    system(“pause”);
    return -1;
    }

    if (!Pattern_Recognition(src))return false;

    namedWindow(“test”, WINDOW_NORMAL);
    imshow(“test”, src);
    waitKey(0);
    system(“pause”);
    return 0;
    }

      四、结果显示

      请添加图片描述


      总结

      本文使用OpenCV C++ 进行基础形状识别,其实原理很简单,主要操作有以下几点。
      1、图像预处理
      2、物体轮廓提取
      3、使用approxPolyDP进行多边形近似,进而统计出该物体的“边”数,从而识别出物体形状。

      • 0
        点赞
      • 0
        收藏
        觉得还不错? 一键收藏
      • 0
        评论
      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

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

      抵扣说明:

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

      余额充值