什么是边缘检测
边缘检测是图像处理与计算机视觉中最重要的技术之一,其目的是检测识别出图像中亮度变化剧烈的像素点构成的集合。图像边缘的正确检测对于分析图像中的内容、实现图像中物体的分割、定位等具有重要的作用。边缘检测大大减少了源图像的数据量,剔除了与目标不相干的信息,保留了图像重要的结构属性。
边缘检测算子是利用图像边缘的突变性质来检测边缘的,通常情况下边缘检测有以下三种类型。
一阶微分:以一阶微分为基础的边缘检测,通过计算图像的梯度值来检测图像边缘,如Sobel算子,Prewitt算子,Roberts算子及差分边缘检测。
二阶微分:以二阶微分为基础的边缘检测,通过寻求二阶导数中的过零点来检测边缘,如拉普拉斯算子,高拉普拉斯算子,Canny算子边缘检测。
混合一阶微分和二阶微分:以混合一阶微分和二阶微分为基础的边缘检测,综合利用一阶微分和二阶微分的特征,如Marr-Hildreth边缘检测算子。
图像差分运算
差分运算通过求图像灰度变化剧烈处的一阶微分算子的极值来检测奇异点,通过奇异点的值进一步设定阈值就可以得到边缘二值化图像。差分边缘检测中差分的水平或垂直方向都与边缘方向正交,因此在实际应用场景中,常常将边缘检测分为水平边缘,垂直边缘以及对角线边缘。
代码演示:
#include<opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp> #include<opencv2/imgproc.hpp> #include<iostream> using namespace cv; using namespace std; void diffOperation(const cv::Mat srcImage, cv::Mat& edgeXImage, cv::Mat& edgeYImage) { cv::Mat tempImage = srcImage.clone(); int nRows = tempImage.rows; int nCols = tempImage.cols; for (int i = 0; i < nRows - 1; i++) { for (int j = 0; j < nCols - 1; j++) { //计算垂直边缘 edgeXImage.at<uchar>(i, j) = abs(tempImage.at<uchar>(i + 1, j) - tempImage.at<uchar>(i, j)); //计算水平边缘 edgeYImage.at<uchar>(i, j) = abs(tempImage.at<uchar>(i, j + 1) - tempImage.at<uchar>(i, j)); } } } int main() { cv::Mat srcImage = cv::imread("C:\\Users\\86173\\Desktop\\lou.jpg",0); if (!srcImage.data) return -1; cv::imshow("srcImage", srcImage); cv::Mat edgeXImage(srcImage.size(), srcImage.type()); cv::Mat edgeYImage(srcImage.size(), srcImage.type()); //计算差分图像 diffOperation(srcImage, edgeXImage, edgeYImage); cv::imshow("edgeXImage", edgeXImage); cv::imshow("edgeYImage", edgeYImage); cv::Mat edgeImage(srcImage.size(), srcImage.type()); //水平与垂直边缘图像叠加 cv::addWeighted(edgeXImage, 0.5, edgeYImage, 0.5, 0.0, edgeImage); cv::imshow("edgeImage", edgeImage); cv::waitKey(0); return 0; }
实现效果:
总结:图像差分运算一般适用于边缘检测水平边缘,垂直边缘以及对角线边缘。