OPENCV——C++版图像形状简单识别

 其实就是简单的小实验,识别图形,opencv的库里是有对应的函数。 首先可以勾勒出他们的轮廓,其次还可以识别哪些是三角形,哪些是圆形,哪些是矩形。
这就是形状、轮廓检测的功能。
预处理
1.灰度
cvtColor(img, imgGray,COLOR_BGR2GRAY, 0);
 2.高斯滤波
GaussianBlur(imgGray, imgBlur, Size(65, 65), 1, 1);
 3.Canny边缘检测
Canny(imgBlur, imgCanny, 40, 120);
 4.膨胀
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
dilate(imgCanny, imgDila, kernel);

形状与轮廓检测函数详解
这里我推荐这位博主的解释,很详尽。 计算机视觉 OpenCV【七:应用之形状与轮廓检测】
具体代码
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void getcontour(Mat imgDil,Mat img)
{
vector<vector<Point>> contour;
vector<Vec4i> hierarchy;
findContours(imgDil, contour, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_TC89_KCOS);
vector<vector<Point>> conPoly(contour.size());
vector<Rect> boundRect(contour.size());
for (int i = 0; i < contour.size(); i++)
{
int area = contourArea(contour[i]);
cout << area << endl;
string objectType;
if (area > 1000)
{
float peri = arcLength(contour[i], true);
approxPolyDP(contour[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"; }
else if (objCor == 4) {
float aspRatio = (float)boundRect[i].width / boundRect[i].height;
cout << aspRatio << endl;
if (aspRatio > 0.95 && aspRatio < 1.05) { objectType = "Square"; }
else { objectType = "Rect"; }
}
else if (objCor > 4) { objectType = "Circle"; }
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 },1,FONT_HERSHEY_PLAIN, Scalar(0, 69, 255), 1);
}
}
}
void main() {
string path = "Resources/shapes.png";
Mat img = imread(path);
Mat imgGray, imgBlur, imgCanny, imgDila, imgErode;
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
cvtColor(img, imgGray,COLOR_BGR2GRAY, 0);
GaussianBlur(imgGray, imgBlur, Size(65, 65), 1, 1);
Canny(imgBlur, imgCanny, 40, 120);
dilate(imgCanny, imgDila, kernel);
getcontour(imgDila,img);
imshow("Image", img);
waitKey(0);
}
窗口里显示了面积,边数,长宽比。 
 
效果还是不错的
|