这次主要进行形状检测代码学习,利用opencv内置函数编写代码,检测出不同的形状。
详见代码:
#include<opencv2/imgcodecs.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<iostream>
using namespace cv;//声明使用opencv命名空间
using namespace std;//声明使用标准库命名空间
//创建函数获取轮廓
void getContours(Mat imgDia, Mat img) {
vector<vector<Point>> contours;//定义轮廓矢量
vector<Vec4i>hierarchy;//定义层次向量
//第一个参数是要输入的图像,第二参数是输出轮廓,第三个参数层次结构,
findContours(imgDia, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE);
//drawContours(img, contours, -1, Scalar(255, 0, 255), 2);//画紫色轮廓
for (int i = 0; i < contours.size(); i++)//i<轮廓次数
{
int area = contourArea(contours[i]);//获取轮廓面积
cout << area << endl;//输出轮廓面积
vector<vector<Point>>conPoly(contours.size());
vector<Rect>boundRect(contours.size());
string objectType;
if (area > 1000)//过滤噪声,这里添加过滤面积条件
{
float peri = arcLength(contours[i], true);//获取闭合轮廓长
//估计轮廓点的个数,但是规则就是以轮廓周长*0.02,获取轮廓角的个数
approxPolyDP(contours[i], conPoly[i], 0.02*peri, true);
cout<<conPoly[i].size()<<endl;//输出轮廓所含有角的个数
boundRect[i]=boundingRect(conPoly[i]);//边界矩形
int objCor = (int)conPoly[i].size();//获取轮廓角的个数,并且整型化
if (objCor == 3){objectType = "Tri";}//三个角为三角形
if (objCor == 4)
{
float aspRatio = (float)boundRect[i].width / (float)boundRect[i].height;
cout << aspRatio << endl;
if (aspRatio > 0.95&&aspRatio < 1.05) { objectType = "Square"; }//四个角长和宽相等为正方形
else { objectType = "Rect"; }//长和宽不相等为矩形
}
if (objCor > 4) { objectType = "Circle"; }//角的个数大于4为圆形
drawContours(img, conPoly, i, Scalar(255, 0, 255), 2);//画出轮廓
rectangle(img, boundRect[i].tl(), boundRect[i].br(), Scalar(0, 255, 0), 5);
putText(img, objectType, { boundRect[i].x,boundRect[i].y - 5 }, FONT_HERSHEY_PLAIN, 1, Scalar(0, 69, 255), 1);
}
}
}
/// importing images
void main()
{
//设置一个路径接受图像
string path = "D:/opencv_study/Resources/shapes.png";//等号右侧为图像路径
Mat img = imread(path);// 创建矩阵接收图像
// Preprocessing
Mat imgGray, imgBlur, imgCanny, imgDia, imgErode;//对所用到的图像矩阵进行矩阵声明
//对图像进行边缘提取,首先要对图像进行灰度化,然后高斯模糊,再进行边缘检测
cvtColor(img, imgGray, COLOR_BGR2GRAY);//对图像进行灰度化
GaussianBlur(imgGray, imgBlur, Size(3, 3), 3, 0);//对图像进行高斯模糊
Canny(imgBlur, imgCanny, 50, 75);//对图像进行canny边缘检测
Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5));
dilate(imgCanny, imgDia, kernel);//粗化边缘线
getContours(imgDia,img);
imshow("Image", img);//imshow显示图像
/*imshow("Image Gray", imgGray);
imshow("Image Blur", imgBlur);
imshow("Image Canny", imgCanny);
imshow("Image Dil", imgDia);*/
//waitkey(0):参数0表示阻塞,程序运行到这即停止
//Waitkey(1):参数1停顿1毫秒,然后继续向下执行
waitKey(0);
}