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

相关推荐
月疯1 小时前
OPENCV摄像头读取视频
人工智能·opencv·音视频
山烛3 小时前
OpenCV:人脸检测,Haar 级联分类器原理
人工智能·opencv·计算机视觉·人脸检测·harr级联分类器
IT古董3 小时前
【第五章:计算机视觉-项目实战之目标检测实战】2.目标检测实战:中国交通标志检测-(2)中国交通标志检测数据格式转化与读取
算法·目标检测·计算机视觉
eqwaak04 小时前
Python Pillow库详解:图像处理的瑞士军刀
开发语言·图像处理·python·语言模型·pillow
IT古董4 小时前
【第五章:计算机视觉-项目实战之图像分割实战】1.图像分割理论-(1)图像分割基础知识:定义、任务描述、应用场景、标注格式
yolo·目标检测·计算机视觉
风已经起了5 小时前
FPGA学习笔记——图像处理之对比度调节(直方图均衡化)
图像处理·笔记·学习·fpga开发·fpga
吃饭睡觉发paper5 小时前
High precision single-photon object detection via deep neural networks,OE2024
人工智能·目标检测·计算机视觉
周杰伦_Jay6 小时前
【图文详解】强化学习核心框架、数学基础、分类、应用场景
人工智能·科技·算法·机器学习·计算机视觉·分类·数据挖掘
蜉蝣之翼❉7 小时前
图像交互工具:像素矩阵与卷积核可视化分析
图像处理
Monkey的自我迭代7 小时前
背景建模(基于视频,超炫)项目实战!
opencv·计算机视觉·音视频