深度学习之Python,OpenCV中的卷积

news2025/7/14 13:00:06

这篇博客将介绍图像内核和卷积。如果将图像视为一个大矩阵,那么图像内核只是一个位于图像顶部的微小矩阵。从左到右和从上到下滑动内核,计算输入图像和内核之间的元素乘法总和——称这个值为内核输出。内核输出存储在与输入图像相同 (x, y) 坐标的输出图像中(在考虑任何填充以确保输出图像具有与输入相同的尺寸后)。

鉴于对卷积的新了解,定义了一个OpenCV和Python函数来将一系列内核应用于图像。包括平滑模糊图像、锐化图像、拉普拉斯内核并检测边缘,sobel_x,y内核查找图像的梯度变化等操作。

最后,简要讨论了核/卷积在深度学习中扮演的角色,特别是卷积神经网络,以及如何自动学习这些过滤器,而不是需要先手动定义它们。手动实现卷积函数是为了明白卷积是怎么计算的,以及opencv自带的卷积函数cv2.filter2D。

1. 效果图

将图像视为大矩阵,将内核视为小矩阵(至少相对于原始的“大矩阵”图像):
内核是一个小矩阵,在较大的图像上从左到右和从上到下滑动。在输入图像中的每个像素处,图像的邻域与内核卷积并存储输出。

在这里插入图片描述
卷积运算符可以应用于 RGB(或其他多通道图像),但为简单起见,这篇博客中仅将过滤器应用于灰度图像。调用 cv2.filter2D将内核应用于灰色图像。cv2.filter2D 函数是opencv自带的,自定义卷积函数的更优化版本

小内核平滑效果图如下:原始图 VS 自己实现的卷积函数效果 VS opencv卷积效果在这里插入图片描述
**大内核平滑如下,随着平均内核大小的增加,输出图像中的模糊量也会增加。
**
在这里插入图片描述
锐化效果如图:
锐化内核强调相邻像素值的差异。这使图像看起来更加生动。
在这里插入图片描述
拉普拉斯边缘检测如图,使用拉普拉斯运算符检测边缘
在这里插入图片描述
sobel x检测图像垂直方向的梯度如图,使用 Sobel 运算符查找垂直边缘
在这里插入图片描述
sobel y检测图像水平方向的梯度如图,使用 Sobel 运算符查找水平边缘
在这里插入图片描述

2. 原理

pip install -U scikit-image

深度学习算法能够在计算机视觉任务中获得前所未有的准确性,包括图像分类、对象检测、分割等。

卷积神经网络依赖于称为卷积 Convolution 的计算机视觉/图像处理技术。CNN 会自动学习在训练过程中应用于输入图像的内核 Kernel。

卷积是计算机视觉和图像处理中最关键、最基本的构建块之一。 实际上(图像)卷积只是两个矩阵的逐元素乘法,后跟一个总和。如之前的平滑、模糊,边缘检测都是卷积。
即卷积是:

  1. 取两个矩阵(它们都具有相同的维度)。
  2. 逐个元素地将它们相乘(即,不是点积,只是简单的乘法)。
  3. 将元素相加。

图像是一个多维矩阵。有宽度,高度,深度——图像中的通道数。对于标准的RGB 图像深度为 3 — 红色、绿色和蓝色通道各对应一个通道。可以将图像视为大矩阵,将核或卷积矩阵视为用于模糊(平均平滑、高斯平滑、中值平滑等)、边缘检测(拉普拉斯、Sobel、Scharr、Prewitt 等)和锐化、边缘检测和其他图像处理功能的微小矩阵。所有这些操作都是专门设计用于执行特定功能的手动定义内核的形式。

从本质上讲,这个微小的内核位于大图像的顶部,从左到右和从上到下滑动,在原始图像的每个(x,y)坐标处应用数学运算(即卷积)。卷积只是内核和内核覆盖的输入图像的邻域之间的逐元素矩阵乘法的总和。。

内核可以是 M x N 像素的任意大小,前提是 M 和 N 都是奇数。通常看到的大多数内核是正方形 N x N 矩阵。使用奇数核大小来确保图像中心有一个有效的整数 (x, y) 坐标。

图像内核是一个小矩阵,用于应用在 Photoshop 或 Gimp 中可能找到的效果,例如模糊、锐化、轮廓或压花(blurring, sharpening, outlining or embossing)。还用于机器学习中的“特征提取”,这是一种确定图像最重要部分的技术。在这种情况下,该过程通常被称为“卷积”

3. 卷积神经网络CNN

上边都是自定义卷积内核,有没有可能定义一种机器学习算法来查看图像并最终学习这些类型的运算符?
事实上,这些类型的算法是神经网络的一种子类型,称为卷积神经网络(Convolutional Neural Networks CNNs)。通过应用卷积滤波器、非线性激活函数、池化和反向传播(nonlinear activation functions, pooling, and backpropagation),CNN 能够学习可以检测网络较低层中的边缘和类似斑点结构的过滤器,然后使用边缘和结构作为构建块,最终检测网络更深层中的更高级别的对象(即面部、猫、狗、杯子等)。

4. 源码

# 将卷积应用于图像
# USAGE
# python convolutions --image images/rb.jpeg

# 导入必要的包
import argparse

import cv2
import imutils
import numpy as np
from skimage.exposure import rescale_intensity  # 应用 scikit-image 的rescale_intensity函数使得输出图像像素位于[0,255]


# 重要的是要了解在图像上“滑动”卷积矩阵,应用卷积,然后存储输出的过程实际上会减少输出图像的空间维度。
# 落在图像边界上的像素没有“中心”像素,空间维度的减小只是对图像应用卷积的副作用。通常希望输出图像与输入图像具有相同的尺寸。
# 为了确保这一点,应用填充。
def convolve(image, kernel):
    # 获取图像的空间维度,及内核的维度
    (iH, iW) = image.shape[:2]
    (kH, kW) = kernel.shape[:2]

    # 为输出图像开辟空间,注意“填充”输入图像的边框,以便空间大小(即宽度和高度)不减小
    pad = (kW - 1) // 2

    # 存在其他填充方法,包括零填充(用零填充边框或复制)和环绕(其中边界像素通过检查图像的另一端来确定)。
    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):
            # 使用 NumPy 数组切片从图像中提取感兴趣区域 (ROI)。ROI是(当前坐标区域的中心)
            roi = image[y - pad:y + pad + 1, x - pad:x + pad + 1]

            # 通过采取在ROI和内核之间逐元素相乘内核,然后对矩阵求和
            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


# 构建命令行参数及解析
# --image 输入图像路径
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=False, default='images/rb.jpeg',
                help="path to the input image")
args = vars(ap.parse_args())

# 构建平均模糊内核以平滑图像,
# 定义了用于模糊/平滑图像的 7 x 7 内核和 21 x 21 内核。内核越大,图像就越模糊。
smallBlur = np.ones((7, 7), dtype="float") * (1.0 / (7 * 7))
largeBlur = np.ones((21, 21), dtype="float") * (1.0 / (21 * 21))

# 使用锐化滤镜sharpening filter
# 定义了一个锐化内核,用于增强图像的线条结构和其他细节。
sharpen = np.array((
    [0, -1, 0],
    [-1, 5, -1],
    [0, -1, 0]), dtype="int")

# 定义拉普拉斯内核执行边缘检测Laplacian kernel,拉普拉斯对于检测图像中的模糊也非常有用。
laplacian = np.array((
    [0, 1, 0],
    [1, -4, 1],
    [0, 1, 0]), dtype="int")

# 定义Sobel x-axis kernel,用于检测图像梯度的垂直变化
sobelX = np.array((
    [-1, 0, 1],
    [-2, 0, 2],
    [-1, 0, 1]), dtype="int")

# 定义Sobel y-axis kernel,用于检测图像梯度的水平变化
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"])
image = imutils.resize(image, width=300)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 遍历内核并展示结果
for (kernelName, kernel) in kernelBank:
    # 卷积运算符当然可以应用于 RGB(或其他多通道图像),但为了简单起见,在此博客文章中仅将过滤器应用于灰度图像
    # 调用 cv2.filter2D将内核应用于灰色图像。cv2.filter2D 函数是上边自定义卷积函数的更优化版本
    print("[INFO] applying {} kernel".format(kernelName))
    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()

参考

  • https://pyimagesearch.com/2016/07/25/convolutions-with-opencv-and-python/
  • https://setosa.io/ev/image-kernels/

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

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

相关文章

数据结构(高阶)—— 红黑树

目录 一、红黑树的概念 二、红黑树的性质 三、红黑树的结点定义 四、红黑树的插入 五、红黑树的验证 六、红黑树与AVL树的比较 一、红黑树的概念 红黑树,是一种二叉搜索树,但在每个结点上增加了一个存储位表示结点的颜色,可以使Red或Bl…

升级打怪拿offer,10w+字总结的Java面试题(附答案)够你刷

升级打怪拿offer,献上熬夜整理最新“10w字总结的Java面试题(附答案)”够你刷! 其包含的内容模块有:基础、JVM、多线程与高并发、Spring、MyBatis、SpringBoot、MYSQL、SpringCloud、Dubbo、Nginx、MQ、数据结构与算法…

CF104064 E. Exchange Students(NWERC2021)

题目分析 首先需要观察到一个性质:在最优方案下的操作一定是首先交换距离最近能交换的两个点来达到交换的效果,这个很好理解:题目要求如果要交换两个人的位置,中间的人的身高必须严格小于这两个人,因此合法的交换操作仅…

生成对抗网络(GAN)

GAN简介 GAN思想是一种二人的零和博弈思想,GAN中有两个博弈者,一个生成器(G),一个判别器(D),这两个模型都有各自的输入和输出。具体功能如下: 生成器(G&…

声门脉冲语音处理

对于 0<t<tpeak&#xff0c;gattack(t) 攻击部分&#xff0c;即上升分支的时间&#xff0c;时间 t 的范围从 0 秒到最大峰值时间 tpeak &#xff0c;图示例中选择为大约总长度的 35%&#xff0c;即 tpeak35%⋅T0&#xff0c;或者在样本 Lattack⌊35%⋅Lg⌉ 中&#xff0c…

2023年系统规划与设计管理师-第三章信息技术服务知识

一. 思维导图 二.IT 服务管理 (ITSM) 1. 什么是 IT 服务管理 (ITSM)&#xff1f; IT 服务管理 (ITSM) 包含一组策略和实践&#xff0c;这些策略和实践可用于为最终用户实施、交付和管理 IT 服务&#xff0c;以满足最终用户的既定需求和企业的既定目标。 在此定义中&#xff0…

otn 709帧结构

otn架构说明: 基于G.709接口,包括波分侧和客户侧,客户侧通常用于互联互通。 光通路净荷单元:OPU0/OPU1/OPU2/OPU3/OPU4/flex,主要用于完成业务同步或异步映射; 光通路数据单元:ODU0/ODU1/ODU2/ODU3/ODU4/ODU-flex,完成通道连接性能监测和子速率复用、 光通路传送单元…

POJ1008:玛雅日历

一、Description During his last sabbatical, professor M. A. Ya made a surprising discovery about the old Maya calendar. From an old knotted message, professor discovered that the Maya civilization used a 365 day long year, called Haab, which had 19 months.…

Netty学习笔记

文章目录二、Netty 入门2.1、概述2.1.1、Netty 是什么&#xff1f;2.1.2、Netty 的作者2.1.3、Netty 的地位2.1.4、Netty 的优势2.2、Hello World2.2.1、目标2.2.2、服务器端2.2.3、客户端2.2.4、流程梳理&#x1f4a1; 提示2.3、组件2.3.1、EventLoop&#x1f4a1; 优雅关闭演…

保姆级二进制安装高可用k8s集群文档(1.23.8)

保姆级二进制安装高可用k8s集群文档k8s搭建方式前期准备集群规划机器准备1、master vagrantfile2、master install.sh3、node vagrantfile4、node install.sh5、时间同步vagran 启动脚本vagrant up注意点安装conntrack 工具ipvs的安装VBoxManage snapshot 准备虚拟机快照ETCD部…

C语言编程作业参考答案

编程题参考答案 文章目录编程题参考答案week1_test选择结构-编程题循环结构上机练习数组编程函数编程2week1_test Write a program to output the average of 2 integers. #include <stdio.h>void main(){int a , b;double c;printf("Please enter 1 integers\n&q…

官网下载mysql 8.0.27及安装

https://www.mysql.com/downloads/&#xff0c;找到社区版下载链接MySQL Community (GPL) Downloads 1、 2、 3、 4、 5、

光谱异常样本检测分析

以近红外光谱为例&#xff0c;大部分光谱数据在不考虑分类问题时&#xff0c;在构建模型前需要对采集数据进行样本分析&#xff0c;以降低因生产过程异常、人为误操作和其他原因对软测量模型的影响&#xff0c;即异常样本检测分析。 按照定义&#xff0c;异常样本检测任务指的是…

k8s编程operator——(3) 自定义资源CRD.md

文章目录1、自定义资源的使用1.1 注册自定义资源1.2 使用自定义资源&#xff1a;1.3 Finalizers1.4 合法性验证2、如何操作自定义资源2.1 使用RestClient和DynamicClient来操作自定义资源对象2.2 使用sharedIndexInformer2.3 code-generator2.3.1 下载安装2.3.2 code-generator…

Ajax、Fetch、Axios三者的区别

1.Ajax&#xff08;Asynchronous JavaScript And XML&#xff09; Ajax 是一个技术统称&#xff0c;它很重要的特性之一就是让页面实现局部刷新。 特点&#xff1a; 局部刷新页面&#xff0c;无需重载整个页面。 简单来说&#xff0c;Ajax 是一种思想&#xff0c;XMLHttpReq…

毕业设计-基于机器学习的图片处理图片倾斜校正

前言 &#x1f4c5;大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科同学来说是充满挑战。为帮助大家顺利通过和节省时间与精力投…

如何简单理解大数据

如何简单理解大数据 HDFS-存储 海量的数据存储 hadoop 只是一套工具的总称&#xff0c;它包含三部分&#xff1a;HDFS&#xff0c;Yarn&#xff0c;MapReduce&#xff0c;功能分别是分布式文件存储、资源调度和计算。 按理来说&#xff0c;这就足够了&#xff0c;就可以完成大…

matlab实现MCMC的马尔可夫转换MS- ARMA - GARCH模型估计

状态转换模型&#xff0c;尤其是马尔可夫转换&#xff08;MS&#xff09;模型&#xff0c;被认为是识别时间序列非线性的不错的方法。 估计非线性时间序列的方法是将MS模型与自回归移动平均 - 广义自回归条件异方差&#xff08;ARMA - GARCH&#xff09;模型相结合&#xff0c;…

Ubuntu22.04+Nvidia驱动+Cuda11.8+cudnn8.6

Ubuntu22.04Nvidia驱动Cuda11.8 一、准备环境 ubuntu 22.04nvidia显卡 这里使用的是RTX3060已安装Python3.10 二、安装pip3 # 安装 sudo apt install python3-pip # 升级 sudo pip3 install --upgrade pip # 如果要卸载&#xff0c;使用命令&#xff1a; sudo apt-get remov…

MySQL创建和管理表

基础知识 一条数据存储的过程 存储数据是处理数据的第一步 。只有正确地把数据存储起来&#xff0c;我们才能进行有效的处理和分析。否则&#xff0c;只能是一团乱麻&#xff0c;无从下手。 那么&#xff0c;怎样才能把用户各种经营相关的、纷繁复杂的数据&#xff0c;有序、…