一、说明
用canny算子、sobel算子、laplacian算子和scharr滤波器可以根据图像像素之间的差异对图像进行边缘检测,但是它只是检测出轮廓边界的像素,而并没有将其组装成连续的轮廓线,而轮廓函数就是做这个的。
二、实例
1. 代码
#include <iostream>
#include <opencv2\opencv.hpp>
using namespace cv;
using namespace std;
//全局变量
Mat image, gray,cannyout,drawing;
int thresh = 80;
int thresh_m = 255;
RNG mrng(12345);
vector<vector<Point>> tours;
vector<Vec4i> rchy;
void on_threshchange(int, void*);//回调函数
int main()
{
//读入图片并显示
image = imread("girl1.jpeg"); //直接以灰度图格式读入也可以
if (!image.data)
printf("图片读取错误");
namedWindow("原图",WINDOW_AUTOSIZE);
imshow("原图", image);
//灰度图,并降噪
cvtColor(image, gray, COLOR_BGR2GRAY);
blur(gray, gray, Size(3, 3)); //yonog用3*3的均值滤波来降噪
//创建滚动条
namedWindow("轮廓检测结果", WINDOW_AUTOSIZE);
createTrackbar("canny阈值", "轮廓检测结果", &thresh, thresh_m, on_threshchange);
on_threshchange(0, 0);
waitKey(0);
return(0);
}
void on_threshchange(int, void*) {
//边缘检测
Canny(gray, cannyout, thresh, thresh * 2, 3);//y一般为1:2或1:3
//寻找轮廓
findContours(cannyout, tours, rchy, RETR_TREE, CHAIN_APPROX_NONE, Point(0, 0)); //在cannyout中寻找轮廓,并保存在tours中
drawing = Mat::zeros(image.size(), CV_8UC3);//定义一个白纸装最后的轮廓结果
//绘制轮廓
for (int i = 0; i < tours.size(); i++) {
Scalar co = Scalar(mrng.uniform(0, 255), mrng.uniform(0, 255), mrng.uniform(0, 255)); //设定颜色为任意值
drawContours(drawing, tours, i, co, 1, 8, rchy, 0, Point());
}
imshow("canny检测结果", cannyout);
imshow("轮廓检测结果", drawing);
}
2. 结果