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);
}
}