c++实现简单的形状识别

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

class ShapeDetector
{
public:
    ShapeDetector();
    ~ShapeDetector();
    void detect(const Mat& curve);
    string get_shape_type();

private:
    string m_shape;
};



ShapeDetector::ShapeDetector()
{
}

ShapeDetector::~ShapeDetector()
{
}

void ShapeDetector::detect(const Mat& curve)
{
    string shape = "unidentified";
    double peri = arcLength(curve, true);//图像轮廓周长
    Mat approx;
    approxPolyDP(curve, approx, 0.04 * peri, true); // 多边形拟合
    const int num_of_vertices = approx.rows;

    // 如果形状是三角形,它将有3个顶点
    if (num_of_vertices == 3)
    {
        shape = "triangle";
    }
    else if (num_of_vertices == 4)
    {// 如果形状具有4个顶点,则可以是正方形或矩形
        //计算轮廓的边界框并使用边界框计算纵横比
        
        Rect rec = boundingRect(approx); //找到最小的矩形
        double ar = 1.0 * rec.width / rec.height;

        // 一个正方形的纵横比大约为等于一,否则形状是一个矩形
        if (ar >= 0.95 && ar <= 1.05)
        {
            shape = "square";
        }
        else
        {
            shape = "rectangle";
        }
    }
    else if (num_of_vertices == 5)
    {// 如果形状是五边形,它将有5个顶点
        shape = "pentagon";
    }
    else
    {// 我们假设形状是一个圆
        shape = "circle";
    }
    m_shape = shape;
}

string ShapeDetector::get_shape_type()
{
    return m_shape;
}



void main(int argc, char* argv[])
{
    const string imgpath = "D:/1.png";
    Mat image = imread(imgpath);
    Mat gray;
    if (image.channels() == 3)//判断图像是否为RGB图,灰度图为1,RGB为3
    {
        cvtColor(image, gray, COLOR_BGR2GRAY);
    }
    else
    {
        gray = image.clone();
    }

    Mat blurred, thresh;
    GaussianBlur(gray, blurred, Size(5, 5), 0.0); //高斯滤波去噪声
    threshold(blurred, thresh, 60, 255, THRESH_BINARY);//图像二值化

    vector< vector<Point> > contours;
    vector<Vec4i> hierarchy;
    findContours(thresh, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);

    ShapeDetector sd;
    vector<Point> c;
    for (size_t i = 0; i < contours.size(); i++)
    {
        c = contours[i];
        Rect crect = boundingRect(c);
        // 计算轮廓的中心,然后检测轮廓的名称
        // 仅使用轮廓形状
        Moments M = moments(c);
        int cX = static_cast<int>(M.m10 / M.m00);
        int cY = static_cast<int>(M.m01 / M.m00);
        sd.detect(Mat(c));
        string shape = sd.get_shape_type();
        drawContours(image, contours, i, Scalar(0, 255, 0), 2);
        Point pt(cX, cY);
        putText(image, shape, pt, FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255, 255, 255), 2);
        imshow("Image", image);
        waitKey(0);
    }
}

Last modification:July 1st, 2020 at 05:03 pm
如果觉得我的文章对你有用,请随意赞赏