[OpenCV] 数字图像处理 C++ 学习——11自定义线性滤波 附完整代码

文章目录

前言

线性滤波用于去噪、平滑、边缘检测等操作。通过定义卷积核(算子)与图像进行卷积,线性滤波器可以有效地提取图像中的特定特征。本文将介绍几种常见的边缘检测算子,包括 Robert算子、Sobel 算子和拉普拉斯算子,并展示如何在 OpenCV 中实现这些滤波器的自定义操作。将提供完整的代码,以便学习使用。

1.理论基础

线性滤波是通过卷积操作实现的。在图像处理中,卷积是指使用一个小的滤波器(也称为卷积核或算子)在图像上移动,将核内的像素值进行加权平均,从而生成新的图像像素值。滤波器可以设计成不同的形状和大小,以实现不同的图像处理效果。

下面是卷积操作的动态过程,可以直观理解卷积:

(1)Roberts 算子 (Roberts Operator)

Roberts 算子是一种简单的边缘检测算子,通过计算图像的水平和垂直方向的差分来检测边缘。它使用两个 2x2 的卷积核来计算梯度的近似值,通常用于检测图像的斜边和锐利的边缘。

​ 水平方向(Roberts X) 垂直方向(Roberts Y):

(2)Sobel 算子 (Sobel Operator)

Sobel 算子是一种一阶导数滤波器,用于检测图像中的边缘。分别计算图像在水平方向和垂直方向上的梯度,通常用于边缘检测。相比 Roberts 算子,Sobel 算子更适合于检测大规模的边缘和平滑噪声。

(3)拉普拉斯算子 (Laplacian Operator)

拉普拉斯算子是一种二阶导数滤波器,用于检测图像中的边缘和细节。它通过计算图像的二阶导数来突出灰度变化较大的区域。

2.代码实现

图片下载链接实验图片链接lena.png

(1)Roberts 算子

Roberts 算子通过计算图像在水平方向和垂直方向的梯度来突出边缘特征,最终在两个窗口中显示使用 Roberts_X 和 Roberts_Y 核滤波后的结果。

cpp 复制代码
/****************************Roberts算子***********************************/
	// 定义Roberts算子核
	Mat Roberts_X = (Mat_<int>(2, 2) << 1, 0, 0, -1);
	Mat Roberts_Y = (Mat_<int>(2, 2) << 0, 1, -1, 0);
	//应用Roberts算子
	Mat Roberts_XFiltered, Roberts_YFiltered, RobertsGradient;
	filter2D(image, Roberts_XFiltered, -1, Roberts_X);
	filter2D(image, Roberts_YFiltered, -1, Roberts_Y);
	cv::imshow("Roberts_X", Roberts_XFiltered);
	cv::imshow("Roberts_Y", Roberts_YFiltered);

Roberts 算子结果:

(2)Sobel 算子

Sobel(image, sobelX, -1, 1, 0, 3);

  • ddepth=-1:输出图像的深度将与输入图像保持一致。
  • dx = 1:表示计算图像在 x 方向上的一阶导数,即水平梯度。
  • dy = 0:表示在 y 方向上不计算导数。
  • ksize = 3:使用 3x3 的 Sobel 核进行卷积操作。
cpp 复制代码
	/****************************Sobel 算子***********************************/
	// 定义Sobel X算子和Sobel Y算子
	Mat sobelX, sobelY;
	Sobel(image, sobelX, -1, 1, 0, 3); // 水平方向
	Sobel(image, sobelY, -1, 0, 1, 3); // 垂直方向
	// 显示结果
	cv::imshow("Sobel X Image", sobelX);
	cv::imshow("Sobel Y Image", sobelY);

Sobel 算子结果:

(3)拉普拉斯算子

一个 3x3 的拉普拉斯算子核,应用于图像以检测边缘。通过 filter2D 函数将该算子核与输入图像进行卷积,可以突出显示图像中的边缘和细节。

cpp 复制代码
/****************************拉普拉斯算子***********************************/
	// 定义3x3拉普拉斯算子
	Mat laplacianKernel = (Mat_<int>(3, 3) << 0, -1, 0, -1, 4, -1, 0, -1, 0);
	Mat laplacianFiltered;
	filter2D(image, laplacianFiltered, -1, laplacianKernel);
	cv::imshow("Laplacian Filtered Image", laplacianFiltered);

拉普拉斯算子结果:

3.完整代码

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

using namespace cv;
using namespace std;

void linear_filtering()
{
	cv::Mat image;
	image = imread("lena.png");
	if (image.empty()) {
		printf("could not find the image...\n");
		return;
	}
	namedWindow("input image", cv::WINDOW_AUTOSIZE);
	cv::imshow("input image", image);
	/**********************Roberts算子*******************************/
	// 定义Roberts算子核
	Mat Roberts_X = (Mat_<int>(2, 2) << 1, 0, 0, -1);
	Mat Roberts_Y = (Mat_<int>(2, 2) << 0, 1, -1, 0);
	//应用Roberts算子
	Mat Roberts_XFiltered, Roberts_YFiltered, RobertsGradient;
	filter2D(image, Roberts_XFiltered, -1, Roberts_X);
	filter2D(image, Roberts_YFiltered, -1, Roberts_Y);
	cv::imshow("Roberts_X", Roberts_XFiltered);
	cv::imshow("Roberts_Y", Roberts_YFiltered);

	/****************************Sobel算子***************************/
	// 定义Sobel X算子和Sobel Y算子
	Mat sobelX, sobelY;
	Sobel(image, sobelX, -1, 1, 0, 3); // 水平方向
	Sobel(image, sobelY, -1, 0, 1, 3); // 垂直方向
	// 显示结果
	cv::imshow("Sobel X Image", sobelX);
	cv::imshow("Sobel Y Image", sobelY);

	/************************拉普拉斯算子***************************/
	// 定义3x3拉普拉斯算子
	Mat laplacianKernel = (Mat_<int>(3, 3) << 0, -1, 0, -1, 4, -1, 0, -1, 0);
	Mat laplacianFiltered;
	filter2D(image, laplacianFiltered, -1, laplacianKernel);
	cv::imshow("Laplacian Filtered Image", laplacianFiltered);

	waitKey(0);
}
int main() 
{
	linear_filtering();
    return 0;
}
相关推荐
炸膛坦客3 分钟前
C++ 学习与 CLion 使用:(四)常量和变量,包括字面常量和符号常量
开发语言·c++·学习
特立独行的猫a11 分钟前
C/C++三方库移植到HarmonyOS平台详细教程(补充版so库和头文件形式)
c语言·c++·harmonyos·napi·三方库·aki
一起搞IT吧27 分钟前
高通Camx hal进程CSLAcquireDeviceHW crash问题分析一:CAM-ICP FW response timeout导致
android·图像处理·数码相机
Kingsdesigner1 小时前
我用Photoshop Firefly+Blender,拯救被环境毁掉的人像大片
图像处理·ui·adobe·社交电子·blender·传媒·photoshop
windSnowLi1 小时前
Python opencv识别图片中重叠圆的圆心位置
开发语言·python·opencv
nenchoumi31192 小时前
手持 Mid360 + RealSense 相机 + Jetson Orin 一体平台
人工智能·目标检测·计算机视觉·机器人·ros
wangluoqi2 小时前
c++ 数据结构-并查集、ST表 小总结
数据结构·c++
时间之里10 小时前
c++:MFC中sqlite3的使用(附实际案例)
c++·mfc·sqlite3
小白要加油努力10 小时前
C++设计模式--策略模式与观察者模式
开发语言·c++·设计模式
John_ToDebug12 小时前
Chrome 内置扩展 vs WebUI:浏览器内核开发中的选择与实践
前端·c++·chrome