Opencv学习笔记(二十三) 改进边缘检测算子-----Marr-Hildresh
2017-10-17 18:33
507 查看
Marr-Hildresh边缘检测算子,用于解决边缘检测的核心问题---定位精度和抑制噪声。Marr-Hildreth算子以高斯函数为平滑算子,结合拉普拉斯算子提取二阶导数的零交叉理论进行边缘检测。边缘检测中灰度变化与图像尺寸无关,检测算子可为不同尺度,灰度变化梯度在一阶导数的极值点(波峰或波谷),或在二阶导数为零的交叉点。
由于噪声点对边缘检测有一定的影响,所以效果更好的边缘检测器是LoG算子。它把高斯平滑滤波器和拉普拉斯锐化滤波器结合起来,先平滑掉噪声,再进行边缘检测,所以效果会更好。
Marr-Hildreth边缘检测代码:
程序运行效果图:
由于噪声点对边缘检测有一定的影响,所以效果更好的边缘检测器是LoG算子。它把高斯平滑滤波器和拉普拉斯锐化滤波器结合起来,先平滑掉噪声,再进行边缘检测,所以效果会更好。
Marr-Hildreth边缘检测代码:
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> using namespace cv; using namespace std; void marrEdge(const Mat src, Mat& result, int kerValue, double delta) { //计算LoG算子 Mat kernel; //半径 int kerLen = kerValue / 2; kernel = Mat_<double>(kerValue, kerValue); //滑窗 for (int i = -kerLen; i <= kerLen; i++) { for (int j = -kerLen; j <= kerLen; j++) { //生成核因子 kernel.at<double>(i + kerLen, j + kerLen) = exp(-((pow(j, 2) + pow(i, 2)) / (pow(delta, 2) * 2))) *((pow(j, 2) + pow(i, 2) - 2 * pow(delta, 2)) / (2 * pow(delta, 4))); } } //设置输入参数 int kerOffset = kerValue / 2; Mat laplacian = (Mat_<double>(src.rows - kerOffset * 2, src.cols - kerOffset * 2)); result = Mat::zeros(src.rows - kerOffset * 2, src.cols - kerOffset * 2, src.type()); double sumLaplacian; //遍历计算卷积图像的拉普拉斯算子 for (int i = kerOffset; i < src.rows - kerOffset; ++i) { for (int j = kerOffset; j < src.cols - kerOffset; ++j) { sumLaplacian = 0; for (int k = -kerOffset; k <= kerOffset; ++k) { for (int m = -kerOffset; m <= kerOffset; ++m) { //计算图像卷积 sumLaplacian += src.at<uchar>(i + k, j + m)*kernel.at<double>(kerOffset + k, kerOffset + m); } } //生成拉普拉斯结果 laplacian.at<double>(i - kerOffset, j - kerOffset) = sumLaplacian; } } for (int y = 1; y < result.rows - 1; ++y) { for (int x = 1; x < result.cols-1; ++x) { result.at<uchar>(y, x) = 0; //领域判定 if (laplacian.at<double>(y - 1, x)*laplacian.at<double>(y + 1, x) < 0) { result.at<uchar>(y, x) = 255; } if (laplacian.at<double>(y, x - 1)*laplacian.at<double>(y, x + 1) < 0) { result.at<uchar>(y, x) = 255; } if (laplacian.at<double>(y + 1, x - 1)*laplacian.at<double>(y - 1, x + 1) < 0) { result.at<uchar>(y, x) = 255; } if (laplacian.at<double>(y - 1, x - 1)*laplacian.at<double>(y + 1, x + 1) < 0) { result.at<uchar>(y, x) = 255; } } } } int main() { Mat srcImage = imread("C:/Users/si/Desktop/2.png"); if (!srcImage.data) return -1; Mat edge,srcGray; cvtColor(srcImage, srcGray, CV_RGB2GRAY); marrEdge(srcGray, edge, 9, 1.6); imshow("srcImage", srcImage); imshow("edge", edge); waitKey(0); return 0; }
程序运行效果图:
相关文章推荐
- OpenCV学习笔记(13)OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑
- OpenCV学习笔记(6)——边缘检测
- opencv学习笔记(二十一) Sobel算子边缘检测
- opencv学习笔记(六)二值化以及边缘检测
- opencv学习笔记(三) 边缘检测
- 对视频流进行边缘检测【OpenCV学习笔记6】
- Unity Shader 学习笔记(20) 卷积、卷积核、边缘检测算子、边缘检测
- openCV学习笔记(二)------图像平滑处理和边缘检测
- python OpenCV学习笔记(十四):边缘检测
- OpenCV-边缘检测算子Marr-Hildreth实现
- OpenCV学习笔记——视频的边缘检测
- 【opencv学习之二十六】边缘检测算子:Canny,Sobel,Laplacian
- 【OpenCV图像处理入门学习教程四】基于LoG算子的图像边缘检测
- 学习【OpenCV入门教程之十二】OpenCV边缘检测:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑---思维导图笔记
- OpenCV 2 学习笔记(24): 使用形态学滤波检测边缘与角点
- OpenCV学习笔记 图像腐蚀模糊和边缘检测
- OpenCV(学习笔记5)-Canny边缘检测
- 【OpenCV学习笔记】十九、图像边缘检测
- Python OpenCV 学习笔记之:Canny边缘检测
- OpenCV学习笔记_图片边缘检测