1.引言
入手目标检测有段时间了,之前一直想着通过论文找解决方案,几篇通读下来,发现论文实验结果挺好看,但并不一定适合自己的项目。经公司前辈指点,针对我们的项目问题,可以用最基本的数字图像处理方法来解决,不管是在效率还是在精度上面都比什么高斯混合模型好,特别是在嵌入式平台,对时间要求非常苛刻。这一篇便理理常用的边缘检测算子(edge detectors)。
2.Sobel算子
2.1Sobel算子
通常用来检测水平和垂直边缘,它的卷积核为:
h1=⎡⎣⎢10−120−210−1⎤⎦⎥
h2=⎡⎣⎢−1−2−1000121⎤⎦⎥
h1 对应的是水平边缘,而 h2 对应的是垂直边缘,opencv实验程序及结果如下:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
void showEdge()
{
Mat img = imread("F:\\c_programing\\dataset\\wall4.jpg");
if (img.empty()){
cout << "图像读取失败!" << endl;
waitKey(0);
exit(EXIT_FAILURE);
}
Mat edgeVertical, edgeHorizontal;
Mat img1;
cvtColor(img, img1, CV_BGR2GRAY);
GaussianBlur(img1, img1, Size(5, 5), 0.0);
double t = (double)getTickCount();
Sobel(img1, edgeHorizontal, CV_8U, 0, 1);
Sobel(img1, edgeVertical, CV_8U, 1, 0);
t = ((double)getTickCount() - t) / getTickFrequency();
printf("Times passed in miliseconds: %f\n" , t * 1000 );
imshow("showImg1", img);
imshow("Horizontal", edgeHorizontal);
imshow("Vertical", edgeVertical);
waitKey();
}
int main()
{
showEdge();
return 0;
}
下图分别为红墙的原图、水平边缘、垂直边缘图:
opencv中的Sobel边缘提取函数为:
CV_EXPORTS_W void Sobel( InputArray src, OutputArray dst, int ddepth,
int dx, int dy, int ksize = 3,
double scale = 1, double delta = 0,
int borderType = BORDER_DEFAULT );
其中ddepth表示输出图像的类型,例如CV_8U;
dx, dy分别表示垂直与水平边缘,取值0或1;
ksize为固定大小3;scale表示导数的倍数;
borderType表示边界扩展类型,卷积核不能处理边缘像素,一般可以镜像反射,或者以特定的值填充若干像素。