OpenCV4.8 开发实战系列专栏之 32 - 图像梯度-更多梯度算子

欢迎大家学习OpenCV4.8 开发实战专栏,长期更新,不断分享源码。
专栏代码全部基于C++ 与Python双语演示。

送相关学习资料, V: OpenCVXueTang_Asst

本文关键知识点:图像梯度-更多梯度算子

图像的一阶导数算子除了sobel算子之外,常见的还有robert算子与prewit算子,它们也都是非常好的可以检测图像的梯度边缘信息,通过0penCV中自定义滤波器,使用自定义创建的robert与prewitt算子就可以实现图像的rober与prewitt梯度边缘检测,OpenCV中的自定义算子滤波函数如下:

Roberts算子与Prewitt算子都是图像处理中用于边缘检测的重要工具,它们在边缘检测方面各有特点和适用场景。以下是对这两种算子的详细比较:

一、定义与原理

  1. Roberts算子

    • 定义:Roberts算子是一种基于图像梯度的边缘检测算法,由Lawrence Roberts在1963年提出。它是一种一阶微分算子,通过计算图像中每个像素的局部灰度变化来识别图像的边缘。
    • 原理:Roberts算子采用局部差分方法来计算图像中的梯度,从而检测边缘。它使用两个3x3的矩阵,分别用于检测水平和垂直方向的边缘。这两个矩阵分别是水平方向(Gx)[1, 0; 0, -1]和垂直方向(Gy)[0, 1; -1, 0]。通过对图像中的每个像素及其周围的像素进行卷积操作,分别计算水平和垂直方向上的梯度分量,然后根据这两个梯度分量计算梯度幅度,表示图像在该像素的边缘强度。
  2. Prewitt算子

    • 定义:Prewitt算子也是一种一阶微分算子的边缘检测,它利用像素点上下、左右邻点的灰度差,在边缘处达到极值来检测边缘。
    • 原理:Prewitt算子的原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成的。这两个方向模板一个检测水平边缘,一个检测垂直边缘。通过对图像中的像素应用这两个模板,可以计算出水平和垂直方向上的梯度分量,从而确定边缘的位置。

二、特点与适用场景

  1. Roberts算子

    • 特点:对边缘明显且噪声较少的图像效果较好,尤其是边缘±45°较多的图像。但由于它对噪声较为敏感,因此在实际应用中通常需要进行降噪处理。
    • 适用场景:适用于边缘明显、噪声较少的图像场景,如某些特定的工业检测、医学影像分析等。
  2. Prewitt算子

    • 特点:Prewitt算子对噪声具有一定的平滑作用,能够去除部分伪边缘。同时,由于它采用3x3的模板进行计算,因此在一定程度上能够抑制噪声的影响。
    • 适用场景:适用于噪声较多、边缘不太明显的图像场景,如自然场景下的物体识别、图像分割等。

三、性能比较

  • 在边缘检测效果方面,Roberts算子对边缘的定位较为准确,但容易受到噪声的影响;而Prewitt算子则能够在一定程度上抑制噪声,但可能会损失一些边缘细节。
  • 在计算复杂度方面,由于Roberts算子和Prewitt算子都采用卷积操作进行计算,因此它们的计算复杂度相对较低,适用于实时性要求较高的应用场景。

四、总结

Roberts算子和Prewitt算子都是图像处理中常用的边缘检测算子。它们各自具有不同的特点和适用场景。在实际应用中,需要根据具体的图像特点和需求选择合适的算子进行边缘检测。同时,也可以考虑结合其他图像处理技术(如降噪、形态学处理等)来提高边缘检测的效果和准确性。

演示代码

cpp 复制代码
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int artc, char** argv) {
	Mat src = imread("D:/images/test.png");
	if (src.empty()) {
		printf("could not load image...\n");
		return -1;
	}
	namedWindow("input", CV_WINDOW_AUTOSIZE);
	imshow("input", src);

	Mat robert_x = (Mat_<int>(2, 2) << 1, 0, 0, -1);
	Mat robert_y = (Mat_<int>(2, 2) << 0, -1, 1, 0);

	Mat prewitt_x = (Mat_<char>(3, 3) << -1, 0, 1,
		-1, 0, 1,
		-1, 0, 1);
	Mat prewitt_y = (Mat_<char>(3, 3) << -1, -1, -1,
		0, 0, 0,
		1, 1, 1);

	Mat robert_grad_x, robert_grad_y, prewitt_grad_x, prewitt_grad_y;
	filter2D(src, robert_grad_x, CV_16S, robert_x);
	filter2D(src, robert_grad_y, CV_16S, robert_y);
	convertScaleAbs(robert_grad_x, robert_grad_x);
	convertScaleAbs(robert_grad_y, robert_grad_y);

	filter2D(src, prewitt_grad_x, CV_32F, prewitt_x);
	filter2D(src, prewitt_grad_y, CV_32F, prewitt_y);
	convertScaleAbs(prewitt_grad_x, prewitt_grad_x);
	convertScaleAbs(prewitt_grad_y, prewitt_grad_y);
	printf("image gradient...");

	imshow("robert x", robert_grad_x);
	imshow("robert y", robert_grad_y);
	imshow("prewitt x", prewitt_grad_x);
	imshow("prewitt y", prewitt_grad_y);

	waitKey(0);
	return 0;
}

python 代码演示

python 复制代码
import cv2 as cv
import numpy as np

src = cv.imread("D:/images/test.png")
cv.namedWindow("input", cv.WINDOW_AUTOSIZE)
cv.imshow("input", src)

robert_x = np.array([[1, 0],[0, -1]], dtype=np.float32)
robert_y = np.array([[0, -1],[1, 0]], dtype=np.float32)

prewitt_x = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=np.float32)
prewitt_y = np.array([[-1, -1, -1], [0, 0, 0], [1, 1, 1]], dtype=np.float32)

robert_grad_x = cv.filter2D(src, cv.CV_16S, robert_x)
robert_grad_y = cv.filter2D(src, cv.CV_16S, robert_y)
robert_grad_x = cv.convertScaleAbs(robert_grad_x)
robert_grad_y = cv.convertScaleAbs(robert_grad_y)

prewitt_grad_x = cv.filter2D(src, cv.CV_32F, prewitt_x)
prewitt_grad_y = cv.filter2D(src, cv.CV_32F, prewitt_y)
prewitt_grad_x = cv.convertScaleAbs(prewitt_grad_x)
prewitt_grad_y = cv.convertScaleAbs(prewitt_grad_y)

# cv.imshow("robert x", robert_grad_x);
# cv.imshow("robert y", robert_grad_y);
# cv.imshow("prewitt x", prewitt_grad_x);
# cv.imshow("prewitt y", prewitt_grad_y);

h, w = src.shape[:2]
robert_result = np.zeros([h, w*2, 3], dtype=src.dtype)
robert_result[0:h,0:w,:] = robert_grad_x
robert_result[0:h,w:2*w,:] = robert_grad_y
cv.imshow("robert_result", robert_result)

prewitt_result = np.zeros([h, w*2, 3], dtype=src.dtype)
prewitt_result[0:h,0:w,:] = prewitt_grad_x
prewitt_result[0:h,w:2*w,:] = prewitt_grad_y
cv.imshow("prewitt_result", prewitt_result)

cv.imwrite("D:/prewitt.png", prewitt_result)
cv.imwrite("D:/robert.png", robert_result)

cv.waitKey(0)
cv.destroyAllWindows()

结束语

学习贵在坚持,学习OpenCV贵在每一天的代码练习,原理跟基本的函数解释,相关知识,后续更新边学边理解,搞技术永远要坚持做长期主义者!我们一起努力!!!

送相关学习资料,V: OpenCVXueTang_Asst

相关推荐
paterWang1 小时前
基于 Python 和 OpenCV 的酒店客房入侵检测系统设计与实现
开发语言·python·opencv
东方佑1 小时前
使用Python和OpenCV实现图像像素压缩与解压
开发语言·python·opencv
C#Thread6 小时前
机器视觉--索贝尔滤波
人工智能·深度学习·计算机视觉
空空转念9 小时前
目前(2025年2月)计算机视觉(CV)领域一些表现优异的深度学习模型
人工智能·深度学习·计算机视觉
IT古董9 小时前
【深度学习】计算机视觉(CV)-图像生成-生成对抗网络(GANs, Generative Adversarial Networks)
深度学习·生成对抗网络·计算机视觉
人工智能学起来9 小时前
多模态机器学习火热idea汇总!
人工智能·深度学习·计算机视觉·transformer
CP-DD14 小时前
目标跟踪(Object Tracking) vs. 目标识别(Object Recognition)
人工智能·计算机视觉·目标跟踪
量子-Alex14 小时前
【目标检测】【YOLOv12】YOLOv12:Attention-Centric Real-Time Object Detectors
人工智能·目标检测·计算机视觉
程序媛小果14 小时前
基于 Python+OpenCV 的疲劳检测系统设计与实现(源码+文档)
开发语言·python·opencv
好评笔记15 小时前
AIGC视频生成明星——Emu Video模型
人工智能·深度学习·机器学习·计算机视觉·面试·aigc·deepseek