在图像中,边界位置才会有梯度,opencv中的常见算子有:

1、Sobel算子

可以有效的提取图像边缘,但是对图像中较弱的边缘提取效果较差

OpenCV 计算物体质量 opencv算子_ci

int main()
{
	cv::Mat img = cv::imread("C:\\Users\\Administrator\\Downloads\\1.jpeg", IMREAD_GRAYSCALE);

	cv::imshow("img", img);

	cv::Mat img_sobel;
	cv::Sobel(img, img_sobel, CV_64F, 1, 0, 3);
	cv::Mat img_sobelx;
	cv::convertScaleAbs(img_sobel, img_sobelx);

	cv::imshow("soblex", img_sobelx);

	cv::Sobel(img, img_sobel, CV_64F, 0, 1, 3);
	cv::Mat img_sobely;
	cv::convertScaleAbs(img_sobel, img_sobely);

	cv::imshow("sobley", img_sobely);

	cv::Mat img_sobelxy;
	cv::addWeighted(img_sobelx, 0.5, img_sobely, 0.5, 0, img_sobelxy);
	cv::imshow("soblexy", img_sobelxy);

	cv::waitKey(0);

	return 0;
}

OpenCV 计算物体质量 opencv算子_计算机视觉_02

2、scharr算子

Scharr算子是对Sobel算子差异性的增强,是通过将滤波器中的权重系数放大来增大像素值间的差异,能有效的提取出较弱的边缘,但两者在检测图像边缘的原理和使用方式上相同

OpenCV 计算物体质量 opencv算子_opencv_03

int main()
{
	cv::Mat img = cv::imread("C:\\Users\\Administrator\\Downloads\\1.jpeg", IMREAD_GRAYSCALE);

	cv::imshow("img", img);

	cv::Mat img_sobel;
	//cv::Sobel(img, img_sobel, CV_64F, 1, 0, 3);
	cv::Scharr(img, img_sobel, CV_64F, 1, 0, 3);
	cv::Mat img_sobelx;
	cv::convertScaleAbs(img_sobel, img_sobelx);

	cv::imshow("soblex", img_sobelx);

	//cv::Sobel(img, img_sobel, CV_64F, 0, 1, 3);
	cv::Scharr(img, img_sobel, CV_64F, 0, 1, 3);
	cv::Mat img_sobely;
	cv::convertScaleAbs(img_sobel, img_sobely);

	cv::imshow("sobley", img_sobely);

	cv::Mat img_sobelxy;
	cv::addWeighted(img_sobelx, 0.5, img_sobely, 0.5, 0, img_sobelxy);
	cv::imshow("soblexy", img_sobelxy);

	cv::waitKey(0);

	return 0;
}

OpenCV 计算物体质量 opencv算子_opencv_04

3、Laplacian算子

1)Laplacian算子具有各方向同性的特点,能够对任意方向的边缘进行提取,具有无方向性的优点,因此使用Laplacian算子提取边缘不需要分别检测X方向的边缘和Y方向的边缘,只需要一次边缘检测即可。
2)Laplacian算子是一种二阶导数算子,对噪声比较敏感,所以需要配合配合高斯滤波一起使用

OpenCV 计算物体质量 opencv算子_计算机视觉_05

int main()
{
	cv::Mat img = cv::imread("C:\\Users\\Administrator\\Downloads\\1.jpeg", IMREAD_GRAYSCALE);

	cv::imshow("img", img);
	
	cv::Mat img_laplacian;
	cv::Laplacian(img, img_laplacian, CV_64F, 3);
	cv::convertScaleAbs(img_laplacian, img_laplacian);
	cv::imshow("laplacian", img_laplacian);

	cv::waitKey(0);

	return 0;
}

OpenCV 计算物体质量 opencv算子_opencv_06

Canny边缘检测

Canny边缘检测算法 是 John F. Canny 于1986年开发出来的一个多级边缘检测算法,也被很多人认为是边缘检测的最优算法,最优边缘检测的三个主要评价标准是:

1、低错误率: 标识出尽可能多的实际边缘,同时尽可能的减少噪声产生的误报。

2、高定位性: 标识出的边缘要与图像中的实际边缘尽可能接近。

3、最小响应: 图像中的边缘只能标识一次。

Canny边缘检测的一般步骤:

去噪:边缘检测容易受到噪声影响,在进行边缘检测前通常需要先进行去噪,一般用高斯滤波去除噪声。

计算梯度:对平滑后的图像采用Sobel算子计算梯度和方向。

OpenCV 计算物体质量 opencv算子_学习_07

计算出来的梯度和方向大概如下图:

OpenCV 计算物体质量 opencv算子_ci_08


非极大值抑制(NMS)

在获取了梯度和方向之后,遍历图像,去除所有不是边界的点。

实现方法:逐个遍历像素点,判断当前像素点是否是周围像素点中具有相同方向梯度的最大值。

下图中,点A,B,C具有相同的方向,梯度方向垂直于边缘。

判断点A是否为A,B,C中的局部最大值,如果是,保留该点;否则,它被抑制(归零)。

OpenCV 计算物体质量 opencv算子_OpenCV 计算物体质量_09


更形象例子:

OpenCV 计算物体质量 opencv算子_OpenCV 计算物体质量_10


滞后阈值

OpenCV 计算物体质量 opencv算子_ci_11

int main()
{
	cv::Mat img = cv::imread("C:\\Users\\Administrator\\Downloads\\26.jpg", IMREAD_GRAYSCALE);

	cv::imshow("img", img);
	cv::Mat edge;

	cv::Canny(img, edge, 100, 200);
	cv::imshow("edge1", edge);

	cv::Canny(img, edge, 64, 128);
	cv::imshow("edge2", edge);
	
	cv::Canny(img, edge, 80, 150);
	cv::imshow("edge3", edge);

	cv::waitKey(0);

	return 0;
}

OpenCV 计算物体质量 opencv算子_计算机视觉_12