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

本文主要介绍如何使用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, rightimage = 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 cv2def convolve(image, kernel):# 输入图像和核的尺寸(iH, iW) = image.shape[:2](kH, kW) = kernel.shape[:2]# 选择pad,卷积后图像大小不变pad = (kW - 1) // 2# 重复最后一个元素,top, bottom, left, rightimage = 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.rhkb.cn/news/313055.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

生成人工智能体:人类行为的交互式模拟论文与源码架构解析(2)——架构分析 - 核心思想环境搭建技术选型

4.架构分析 4.1.核心思想 超越一阶提示,通过增加静态知识库和信息检索方案或简单的总结方案来扩展语言模型。 将这些想法扩展到构建一个代理架构,该架构处理检索,其中过去的经验在每个时步动态更新,并混合与npc当前上下文和计划…

c++ qt6.5 打包sqlite组件无法使用,尽然 也需要dll支持!这和开发php 有什么区别!

运行 程序会默认使用当前所在文件夹中的 dll 文件,若文件不存在,会使用系统环境变量路径中的文件;又或者是需要在程序源代码中明确指定使用的 dll 的路径。由于我安装 Qt 时将相关 dll 文件路径都添加到了系统环境变量中,所以即使…

.net反射(Reflection)

文章目录 一.概念:二.反射的作用:三.代码案例:四.运行结果: 一.概念: .NET 反射(Reflection)是指在运行时动态地检查、访问和修改程序集中的类型、成员和对象的能力。通过反射,你可…

C语言通过键盘输入给结构体内嵌的结构体赋值——指针法

1 需求 以录入学生信息&#xff08;姓名、学号、性别、出生日期&#xff09;为例&#xff0c;首先通过键盘输入需要录入的学生的数量&#xff0c;再依次输入这些学生的信息&#xff0c;输入完成后输出所有信息。 2 代码 #include<stdio.h> #include<stdlib.h>//…

React - 基础学习

React基础 React更新视图的流程 是 一层一层查找 到对应的视图做更新 如何生成React工程 // 生成简单的react npx create-react-app react-app// 生成typescript的react npx create-react-app react-app-ts --template typescriptReact的基本能力 父子组件 // 父组…

openGauss学习笔记-265 openGauss性能调优-TPCC性能调优测试指导-操作系统配置

文章目录 openGauss学习笔记-265 openGauss性能调优-TPCC性能调优测试指导-操作系统配置265.1安装openEuler操作系统265.2 修改操作系统内核PAGESIZE为64KB。265.3 关闭CPU中断的服务irqbalance openGauss学习笔记-265 openGauss性能调优-TPCC性能调优测试指导-操作系统配置 本…

OpenCV基本图像处理操作(八)——光流估计

光流估计 光流估计是一种用于检测图像序列中像素点运动的技术。它基于这样的假设&#xff1a;在连续的视频帧之间&#xff0c;一个物体的移动会导致像素强度的连续性变化。通过分析这些变化&#xff0c;光流方法可以估计每个像素点的运动速度和方向。 光流估计通常用于多种应…

idea 将项目上传到gitee远程仓库具体操作

目录标题 一、新建仓库二、初始化项目三、addcommit四、配置远程仓库五、拉取远程仓库内容六、push代码到仓库 一、新建仓库 新建仓库教程 注意&#xff1a;远程仓库的初始文件不要与本地存在名字一样的文件&#xff0c;不然拉取会因为冲突而失败。可以把远程一样的初始文件删…

Labview2024安装包(亲测可用)

目录 一、软件简介 二、软件下载 一、软件简介 LabVIEW是一种由美国国家仪器&#xff08;NI&#xff09;公司开发的程序开发环境&#xff0c;它显著区别于其他计算机语言&#xff0c;如C和BASIC。传统的计算机语言是基于文本的语言来产生代码&#xff0c;而LabVIEW则采用图形化…

HEF4046BT功能参数及避免使用的场景、应用前置放大器

制造商:NXP 产品种类:锁相环 PLL 类型:PLL 电路数量:1 电源电压 最大:15 V 电源电压 最小:3 V 最大工作温度: 85 C 安装风格:SMD/SMT 封装:SO-16 封装:Bulk 商标:NXP Semiconductors 最小工作温度:- 40 C 工作电源电压:3.3 V, 5 V, 9 V, 12 V HEF4046BT 是一种 CMO…

LINUX中使用cron定时任务被隐藏,咋回事?

一、问题现象 线上服务器运行过程中&#xff0c;进程有莫名进程被启动&#xff0c;怀疑是有定时任务自动启动&#xff0c;当你用常规方法去查看&#xff0c;比如使用crontab去查看定时器任务&#xff0c;提示no crontab for root 或者使用cat到/var/spool/cron目录下去查看定时…

Linux编辑器-vim的使用

vim的基本概念 vim的三种模式(其实有好多模式&#xff0c;目前掌握这3种即可),分别是命令模式&#xff08;command mode&#xff09;、插 入模式&#xff08;Insert mode&#xff09;和底行模式&#xff08;last line mode&#xff09;&#xff0c;各模式的功能区分如下&#…

027——从GUI->Client->Server->driver实现对SR501的控制

目录 1、修改显示界面 2、 添加对SR501显示的处理和tcp消息的处理 3、 在服务器程序中添加对SR501的处理 4、 编写驱动句柄 5、 修改底层驱动 1、修改显示界面 有个奇怪的问题这里的注释如果用 就会报错不知道为啥&#xff0c;只能用#来注释 我把显示这里需要显示的器件的…

nginx部署上线

1. windows配置nginx 打包命令 npm run build:prod 1. 安装 nginx mac windows 2. mac / windows 环境下ngnix部署启动项目 2. nginx 解决 history 的 404 问题 3. nginx配置代理解决生产环境跨域问题

Docker构建Golang项目常见问题

Docker构建Golang项目常见问题 1 dockerfile报错&#xff1a;failed to read expected number of bytes: unexpected EOF2 go mod tidy: go.mod file indicates go 1.21, but maximum supported version is 1.17 1 dockerfile报错&#xff1a;failed to read expected number o…

rhce.定时任务和延迟任务项目

一 . 在系统中设定延迟任务要求如下&#xff1a; 在系统中建立 easylee 用户&#xff0c;设定其密码为 easylee 延迟任务由 root 用户建立 要求在 5 小时后备份系统中的用户信息文件到/backup中 确保延迟任务是使用非交互模式建立 确保系统中只有 root 用户和easylee用户可以…

minio如何配置防盗链

MinIO 是一个开源的对象存储服务器&#xff0c;用于存储大量的数据&#xff0c;同时提供了丰富的功能和 API。配置防盗链可以帮助你控制谁可以访问存储在 MinIO 上的对象。以下是在 MinIO 中配置防盗链的一般步骤&#xff1a; 编辑 config.json 文件&#xff1a; 找到 MinIO 服…

网工交换技术基础——VLAN原理

1、VLAN的概念&#xff1a; VLAN(Virtual LAN)&#xff0c;翻译成中文是“虚拟局域网”。LAN可以是由少数几台家用计算机构成的网络&#xff0c;也可以是数以百计的计算机构成的企业网络。VLAN所指的LAN特指使用路由器分割的网络——也就是广播域。 2、VLAN的主要作用&#xf…

『Django』创建app(应用程序)

theme: smartblue 本文简介 点赞 关注 收藏 学会了 在《『Django』环境搭建》中介绍了如何搭建 Django 环境&#xff0c;并且创建了一个 Django 项目。 在刚接触 Django 时有2个非常基础的功能是需要了解的&#xff0c;一个是“app”(应用程序)&#xff0c;另一个是 url(路由…

35. UE5 RPG制作火球术技能

接下来&#xff0c;我们将制作技能了&#xff0c;总算迈进了一大步。首先回顾一下之前是如何实现技能触发的&#xff0c;然后再进入正题。 如果想实现我之前的触发方式的&#xff0c;请看此栏目的31-33篇文章&#xff0c;讲解了实现逻辑&#xff0c;这里总结一下&#xff1a; …