要想实现轮廓检测,首先我们需要对待检测的图像进行图像处理:
图像灰度化、高斯滤波、Canny 边缘检测、边缘检测放大处理、提取轮廓。
一、实现简单的全图型检测
即只要将drawContours第三个参数设置为-1 既能实现图像的全图型检测。
程序:
#include
#include // 说是说gui 具体什么gui 不清楚
#include // 图像头文件
#include // 图像处理头文件
using namespace std;
using namespace cv;
/*要进行图像形貌检测之前
*首先要二值化,再进行滤波处理,再进行Canny边缘检测
*最后才能检测出图形轮廓
*/
Mat imgGray, imgBlur, imgCanny,imgDil;
void getContours(Mat imgDil,Mat& img);
int main()
{
string path = "resources/shapes.png"; // 导入图形的时候,先要在右边点击显示所有文件!!!
Mat img = imread(path); // 在opencv 中所有的图像信息都使用Mat
// pre-processing image 图像预处理
cvtColor(img, imgGray, COLOR_BGR2GRAY);
GaussianBlur(imgGray, imgBlur,Size(3,3),3,0); // 高斯滤波
Canny(imgBlur, imgCanny, 25, 75);// Canny 边缘检测
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3)); // 其中 Size 和 边缘检测的放大倍数有关系
dilate(imgCanny, imgDil, kernel);
getContours(imgDil,img); // 第一个参数 是寻找轮廓的参数, 第二个参数是显示图案的参数
imshow("Image", img);
waitKey(0); // 延时,0即相当于无穷大
}
void getContours(Mat imgDil, Mat& img)
{
/* contour is a vector inside that vector there is more vector
* { {Point(20,30),Point(50,60)},{},{}} each vector like a contour and each contour have some points
*
**/
vector> contours;
vector hierarchy; // Vec4i 即代表该向量内有4个 int 变量typedef Vec Vec4i; 这四个向量每一层级代表一个轮廓
findContours(imgDil, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); // CV_CHAIN_APPROX_SIMPLE - 简单的链式接近法
drawContours(img, contours, -1, Scalar(255,0,255),2); // contouridx = -1 代表需要绘制所检测的所有轮廓
}
运行结果:
细心的读者会发现,该程序还将微小的瑕疵检测到了。
二、去除轮廓瑕疵
去除瑕疵的方法很简单,即先检测所有图形的面积,发现图形中的最小面积,即为瑕疵面积(假设我们已知该瑕疵面积<1000),之后使用if进行面积过滤。
程序:
#include
#include // 说是说gui 具体什么gui 不清楚
#include // 图像头文件
#include // 图像处理头文件
using namespace std;
using namespace cv;
/*要进行图像形貌检测之前
*首先要二值化,再进行滤波处理,再进行Canny边缘检测
*最后才能检测出图形轮廓
*/
Mat imgGray, imgBlur, imgCanny,imgDil;
void getContours(Mat imgDil,Mat& img);
int main()
{
string path = "resources/shapes.png"; // 导入图形的时候,先要在右边点击显示所有文件!!!
Mat img = imread(path); // 在opencv 中所有的图像信息都使用Mat
// pre-processing image 图像预处理
cvtColor(img, imgGray, COLOR_BGR2GRAY);
GaussianBlur(imgGray, imgBlur,Size(3,3),3,0); // 高斯滤波
Canny(imgBlur, imgCanny, 25, 75);// Canny 边缘检测
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3)); // 其中 Size 和 边缘检测的放大倍数有关系
dilate(imgCanny, imgDil, kernel);
getContours(imgDil,img); // 第一个参数 是寻找轮廓的参数, 第二个参数是显示图案的参数
imshow("Image", img);
waitKey(0); // 延时ÿ