OpenCV从入门到精通实战(七)——探索图像处理:自定义滤波与OpenCV卷积核

news2024/11/23 3:46:02

本文主要介绍如何使用Python和OpenCV库通过卷积操作来应用不同的图像滤波效果。主要分为几个步骤:图像的读取与处理、自定义卷积函数的实现、不同卷积核的应用,以及结果的展示。

卷积

在图像处理中,卷积是一种重要的操作,它通过将图像与一个小的矩阵(称为卷积核或滤波器)进行运算来影响图像的各种属性。这种操作可以用于实现模糊、锐化、边缘检测等效果。今天,我们将探讨如何在Python中使用OpenCV库来自定义卷积核,并将其应用于图像处理任务中。

图像的读取与处理

首先,我们需要读取一张图像,并将其转换成灰度图,因为在这个例子中我们将使用灰度图像来简化处理过程:

image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

自定义卷积函数的实现

接下来,我们实现一个名为convolve的函数,该函数接收一个图像和一个卷积核作为输入,并返回卷积后的结果。在这个过程中,我们通过为图像添加边界,然后对每个像素应用卷积核来完成卷积操作:

def convolve(image, kernel):
	# 输入图像和核的尺寸
	(iH, iW) = image.shape[:2]
	(kH, kW) = kernel.shape[:2]

	# 选择pad,卷积后图像大小不变
	pad = (kW - 1) // 2
	# 重复最后一个元素,top, bottom, left, right
	image = cv2.copyMakeBorder(image, pad, pad, pad, pad,
		cv2.BORDER_REPLICATE)
	output = np.zeros((iH, iW), dtype="float32")

	# 卷积操作
	for y in np.arange(pad, iH + pad):
		for x in np.arange(pad, iW + pad):
			# 提取每一个卷积区域
			roi = image[y - pad:y + pad + 1, x - pad:x + pad + 1]

			# 内积运算
			k = (roi * kernel).sum()

			# 保存相应的结果
			output[y - pad, x - pad] = k

	# 将得到的结果放缩到[0, 255]
	output = rescale_intensity(output, in_range=(0, 255))
	output = (output * 255).astype("uint8")

	return output

不同卷积核的应用

为了展示不同的图像处理效果,我们定义了几种不同的卷积核:

  • **小模糊(Small Blur)大模糊(Large Blur)**用于创建模糊效果。
  • **锐化(Sharpen)**卷积核可以使图像看起来更清晰。
  • **拉普拉斯(Laplacian)索贝尔(Sobel)**卷积核用于边缘检测。
smallBlur = np.ones((7, 7), dtype="float") * (1.0 / (7 * 7))
largeBlur = np.ones((21, 21), dtype="float") * (1.0 / (21 * 21))
# 尝试不同的卷积核
sharpen = np.array((
	[0, -1, 0],
	[-1, 5, -1],
	[0, -1, 0]), dtype="int")

laplacian = np.array((
	[0, 1, 0],
	[1, -4, 1],
	[0, 1, 0]), dtype="int")


sobelX = np.array((
	[-1, 0, 1],
	[-2, 0, 2],
	[-1, 0, 1]), dtype="int")

sobelY = np.array((
	[-1, -2, -1],
	[0, 0, 0],
	[1, 2, 1]), dtype="int")

# 尝试不同结果
kernelBank = (
	("small_blur", smallBlur),
	("large_blur", largeBlur),
	("sharpen", sharpen),
	("laplacian", laplacian),
	("sobel_x", sobelX),
	("sobel_y", sobelY)
)

# 更多卷积核...

结果的展示

最后,我们遍历每一个卷积核,将其应用于原始图像,并显示结果:

for (kernelName, kernel) in kernelBank:
    convoleOutput = convolve(gray, kernel)
    opencvOutput = cv2.filter2D(gray, -1, kernel)
    # 展示结果
    # 分别展示结果
	cv2.imshow("original", gray)
	cv2.imshow("{} - convole".format(kernelName), convoleOutput)
	cv2.imshow("{} - opencv".format(kernelName), opencvOutput)
	cv2.waitKey(0)
	cv2.destroyAllWindows()

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可以看到卷积核在图像处理中的强大作用,以及如何通过调整卷积核来实现不同的视觉效果。

完整代码

# 导入工具包
from skimage.exposure import rescale_intensity
import numpy as np
import argparse
import cv2

def convolve(image, kernel):
	# 输入图像和核的尺寸
	(iH, iW) = image.shape[:2]
	(kH, kW) = kernel.shape[:2]

	# 选择pad,卷积后图像大小不变
	pad = (kW - 1) // 2
	# 重复最后一个元素,top, bottom, left, right
	image = cv2.copyMakeBorder(image, pad, pad, pad, pad,
		cv2.BORDER_REPLICATE)
	output = np.zeros((iH, iW), dtype="float32")

	# 卷积操作
	for y in np.arange(pad, iH + pad):
		for x in np.arange(pad, iW + pad):
			# 提取每一个卷积区域
			roi = image[y - pad:y + pad + 1, x - pad:x + pad + 1]

			# 内积运算
			k = (roi * kernel).sum()

			# 保存相应的结果
			output[y - pad, x - pad] = k

	# 将得到的结果放缩到[0, 255]
	output = rescale_intensity(output, in_range=(0, 255))
	output = (output * 255).astype("uint8")

	return output

# 指定输入图像
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", default="lanpangzi.jpg",
	help="path to the input image")
args = vars(ap.parse_args())

# 分别构建两个卷积核
smallBlur = np.ones((7, 7), dtype="float") * (1.0 / (7 * 7))
largeBlur = np.ones((21, 21), dtype="float") * (1.0 / (21 * 21))

# 尝试不同的卷积核
sharpen = np.array((
	[0, -1, 0],
	[-1, 5, -1],
	[0, -1, 0]), dtype="int")

laplacian = np.array((
	[0, 1, 0],
	[1, -4, 1],
	[0, 1, 0]), dtype="int")


sobelX = np.array((
	[-1, 0, 1],
	[-2, 0, 2],
	[-1, 0, 1]), dtype="int")

sobelY = np.array((
	[-1, -2, -1],
	[0, 0, 0],
	[1, 2, 1]), dtype="int")

# 尝试不同结果
kernelBank = (
	("small_blur", smallBlur),
	("large_blur", largeBlur),
	("sharpen", sharpen),
	("laplacian", laplacian),
	("sobel_x", sobelX),
	("sobel_y", sobelY)
)

# 简单起见,用灰度图来玩
image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 遍历每一个核
for (kernelName, kernel) in kernelBank:

	print("[INFO] applying {} kernel".format(kernelName))
	convoleOutput = convolve(gray, kernel)
	# -1 表示深度一致
	opencvOutput = cv2.filter2D(gray, -1, kernel)

	# 分别展示结果
	cv2.imshow("original", gray)
	cv2.imshow("{} - convole".format(kernelName), convoleOutput)
	cv2.imshow("{} - opencv".format(kernelName), opencvOutput)
	cv2.waitKey(0)
	cv2.destroyAllWindows()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1606284.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JAVA网络编程、项目验证码实现

什么是网络编程? 在网络通信协议下,不同计算机上运行的程序,进行的数据传输。 应用场景:即时通信、网游对战、金融证券、国际贸易、邮件、等等 不管是什么场景,都是计算机跟计算机之间通过网络进行数据传输 Java中可以使用ja…

面试经典算法系列之二叉树17 -- 验证二叉树

面试经典算法32 - 验证二叉树 LeetCode.98 公众号:阿Q技术站 问题描述 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下: 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当…

浅写个登录(无js文件)

全部代码如下&#xff0c;无需编写wxss文件&#xff0c;渲染都在style里面&#xff1a; <view style"height: 250rpx;width: 100%;"> <!-- 背景图片 --><view style"position: absolute; background-color: antiquewhite; height: 250rpx;width…

OpenHarmony UI动画-recyclerview_animators

简介 带有添加删除动画效果以及整体动画效果的list组件库 下载安装 ohpm install ohos/recyclerview-animatorsOpenHarmony ohpm 环境配置等更多内容&#xff0c;请参考如何安装OpenHarmony ohpm 包 使用说明 引入组件库 import { RecyclerView } from "ohos/recycler…

RabbitMQ项目实战(一)

文章目录 RabbitMQ项目实战选择客户端基础实战 前情提要&#xff1a;我们了解了消息队列&#xff0c;RabbitMQ的入门&#xff0c;交换机&#xff0c;以及核心特性等知识&#xff0c;现在终于来到了激动人心的项目实战环节&#xff01;本小节主要介绍通过Spring Boot RabbitMQ S…

UI5 快速入门教程

环境准备 node >16.8 ,VSCode&#xff0c;官方网址 开始 创建一个根文件夹&#xff0c;根文件中创建一个package.json文件 {"name": "quickstart-tutorial","private": true,"version": "1.0.0","author":…

吴恩达<用于LLM应用程序开发的LangChain> L1-Model_prompt_parser

问题预览/关键词 课程地址如何获取openAI的API Key如何根据日期设置不同模型?如何调用OpenAI的API?如何使用OpenAI的API&#xff1f;langchain如何抽象OpenAI的API接口&#xff1f;langchain如何创建提示词模板并查看模板内容&#xff1f;langchain如何使用提示词模板生成提…

【opencv】dnn示例-vit_tracker.cpp 使用OpenCV库和ViTTrack模型实现的视频追踪程序

这段代码是一个使用OpenCV库和ViTTrack模型实现的视频追踪程序。程序通过摄像头或视频文件获取图像序列&#xff0c;并对选定的目标对象进行实时追踪。 代码主要分为以下几个部分&#xff1a; 导入必要的库&#xff1a;程序开始时先导入了iostream&#xff0c;cmath以及相关Ope…

每日两题 / 53. 最大子数组和 56. 合并区间(LeetCode热题100)

53. 最大子数组和 - 力扣&#xff08;LeetCode&#xff09; 经典dp题&#xff0c;dp[i]表示以nums[i]为结尾的所有子数组中&#xff0c;最大的和 将i从左到右遍历&#xff0c;考虑dp[i]如何维护&#xff1f; 以nums[i]结尾的子数组只有两种情况&#xff0c;子数组只有nums[i]…

[Qt网络编程]之UDP通讯的简单编程实现

hello&#xff01;欢迎大家来到我的Qt学习系列之网络编程之UDP通讯的简单编程实现。希望这篇文章能对你有所帮助&#xff01;&#xff01;&#xff01; 本篇文章的相关知识请看我的上篇文章: http://t.csdnimg.cn/UKyeM 目录 UDP通讯 基于主窗口的实现 基于线程的实现 UDP通讯…

小黄脸404自动跳转源码

源码介绍 小黄脸404自动跳转源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面&#xff0c;重定向这个界面 效果截图 源码下载 小黄脸404自动跳转…

网络防火墙技术知多少?了解如何保护您的网络安全

在当前以网络为核心的世界中&#xff0c;网络安全成为了至关重要的议题。网络防火墙是一种常见的保护网络安全的技术&#xff0c;用于监控和控制网络流量&#xff0c;阻止未经授权的访问和恶意活动。今天德迅云安全就带您了解下防火墙的一些相关功能和类型。 防火墙的五个功能…

【EI会议征稿通知】2024年图像处理、机器学习与模式识别国际学术会议(IPMLP 2024)

2024年图像处理、机器学习与模式识别国际学术会议&#xff08;IPMLP 2024) 2024 International Conference on Image Processing, Machine Learning and Pattern Recognition 重要信息 大会官网&#xff1a;www.ipmlp.net&#xff08;点击参会/投稿/了解会议详情&#xff09;…

【操作系统】(Operator System)

目录 1.概念2.系统调用和库函数 1.概念 1.操作系统是什么呢&#xff1f;&#xff1f; 操作系统是一款进行软硬件资源管理的软件&#xff0c;我们打开电脑第一个加载的软件就是操作系统。 2.为什么要有操作系统呢&#xff1f; 操作系统通过将软硬件资源管理好(手段)&#xf…

axios的封装理解和基本使用

axios的配置 ruoyi的前端对axios进行了封装&#xff0c;让我们发get请求或者是post请求更加方便了。 ruoyi对axios的封装在下面文件中&#xff1a;打开文件&#xff0c;可以看到它有三个显眼的方法&#xff0c;分别是request拦截器、response拦截器和通用下载方法。ruoYi接口地…

ansible进阶-剧本调试方法

目录 1、调试方法 2、实例 2.1 Debug模块 2.2 tags标签 2.3 忽略错误 1、调试方法 具体方法应用场景debug标签执⾏剧本的时候输出剧本的执⾏流程,⼀般配合register⼀起使⽤. 输出facts变量自定义变量tags标签给⼀些模块加上标签,运⾏剧本的时候可以运⾏指定标签的…

基于非线性控制策略的电力电子电路——DC-DC电路的3种滑模控制器【MATLAB/simulink】

第一种&#xff0c;滞环滑模控制器Buck电路 在滑模控制系统中&#xff0c;采用滞环技术&#xff0c;直接将切换函数转换成开关控制信号&#xff0c;滞环技术被看做一种降低系统结构的切换频率的调制方法&#xff0c;业界也把基于滞环滑模技术实现的滑模控制称为直接滑模控制技…

【ESP32 手机配网教程】

【ESP32 手机配网教程】 1. 前言2. 先决条件2.1 环境配置2.2 所需零件3.3 硬件连接步骤 3. Web热点手动配网3.1. 准备工作3.2. 编译上传程序3.3. 进行手动配网 4. BLE无线配网4.1. 准备工作**4.2. 编译上传程序4.3. 使用手机APP进行无线配网 5. 总结 1. 前言 欢迎使用ESP32进行…

【C++】list的介绍及使用说明

目录 00.引言 01.list的介绍 模版类 独立节点存储 list的使用 1.构造函数 2.迭代器的使用 分类 运用 3.容量管理 empty()&#xff1a; size(): 4.元素访问 5.增删查改 00.引言 我们学习数据结构时&#xff0c;学过两个基本的数据结构&#xff1a;顺序表和链表。顺…

基于simulink的模拟锁相环和数字锁相环建模与对比仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 模拟锁相环&#xff08;PLL&#xff09;的基本原理 4.2 数字锁相环&#xff08;DPLL&#xff09;的基本原理 5.完整工程文件 1.课题概述 模拟锁相环和数字锁相环建模的simulink建模&#xff0c;对…