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

2023-11-18

这篇博客将介绍图像内核和卷积。如果将图像视为一个大矩阵,那么图像内核只是一个位于图像顶部的微小矩阵。从左到右和从上到下滑动内核,计算输入图像和内核之间的元素乘法总和——称这个值为内核输出。内核输出存储在与输入图像相同 (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()

参考

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深度学习之Python,OpenCV中的卷积 的相关文章

随机推荐

  • 微信小程序-input标签无法输入数据问题

    使用微信开发者工具学习时 input标签点击之后鼠标无法跳转 也无法输入数据 解决方案 直接单击键盘的 Tab键即可跳入输入框 鼠标未在输入框内 按一下Tab键也可跳入
  • Vue脚手架相关笔记(ref属性、props配置、mixin混入、scoped样式)

    关于不同版本的Vue 1 vue js 与vue runtime xxx js的区别 1 vue js是完整版的Wue 包含 核心功能 模板解析器 2 vue runtime xxx js是运行版的Vue 只包含 核心功能 没有模板解析器
  • Sysrv-hello挖矿病毒

    麻蛋我的服务器也中了这个挖矿病毒 先看一下网上能找到的文章吧 https developer aliyun com article 780758 讲了一大堆原理 你倒是给我解决办法啊 1 先杀了进程 sysrv network01 2 修改
  • H5打开新窗口与页面跳转的几种方法

    1 在本窗体打开一个新的页面 window location href URL 2 在一个新的窗口打开一个新的页面 window open URL 3 本窗口的页面被替换为一个新的页面URL 替换后不可以回退到上个页面 location r
  • 理光打印机出现sc542-01怎样解决?

    问题图 步骤一图文 补充 理光维修模式指令 107 03以下机型 143 通用 806182 03以上机型 注方法 1 清除键 黄色 点一次 107 停止键 红色键 按住3秒以上 2 依次按重置 RESET 806182 按住C不动3秒 就
  • CentOS7.5最小化安装之后的配置

    我是最小化安装的 安装了之后很多基本使用配置没有 接下来要做一些配置 如网络之类的 使系统可用 1 使命令分页显示 1页显示不不下 又不能上翻页 xxx more 2 查看系统安装了哪些软件包 rpm qa 3 配置网络 最小化安装之后 i
  • 听我一句劝,别去外包,干了3个月,技术退步明显...

    先说一下自己的情况 大专生 18年通过校招进入湖南某软件公司 干了接近4年的功能测试 今年年初 感觉自己不能够在这样下去了 长时间呆在一个舒适的环境会让一个人堕落 而我已经在一个企业干了四年的功能测试 已经让我变得不思进取 谈了2年的女朋友
  • 一种关于单片机定时器中断和数码管冲突问题的解决方案

    问题发现 我们会发现 同时存在定时器中断和数码管操作时 有时会导致数码管显示异常 原因探究 在定时器中断函数中不要操作P2和P0 因为定时器 T 和主板 M 的时钟频率不一样 有可能导致M刚操作完P2 T又去操作P0 导致正确的P2和P0没
  • Windows从命令行创建文本文件的两种方式

    第一种方式 copy con 文件名 然后可以输入文件内容 完成后打Ctrl Z退出 输入的内容被保存为一个文件 第二种 如下 echo gt 文件名 创建一个空的文件 当然你可以创建任何后缀名的文本类文件 创建一个SQL文件也是没问题的
  • 教你更优雅的写法处理null检查

    回顾以前对null的处理方式 public class OptionalTest public static void main String args test01 小黑 test01 null public static void te
  • View.VISIBLE、INVISIBLE、GONE的区别

    View VISIBLE INVISIBLE GONE的区别 android中UI应用的开发中经常会使用view setVisibility 来设置控件的可见性 其中该函数有3个可选值 他们有着不同的含义 View VISIBLE gt 可
  • Qt事件和事件循环

    在处理QT循环事件的时候遇到了问题 查了半天资料都没弄明白问题出在哪 后来找大牛同事问了一下 同事就给我写了QCoreApplication processEvent 这个函数 好啦 终于搞定了 这里小记一下 以免以后遇到 于是乎这里认真仔
  • Your account has been blocked问题解决

    更新代码时报错 如下 branches to build service 1 get branch service to dir service only update code Your account has been blocked
  • 2020规划调整,以自研引擎和osg/osgearth源码分析为主

    随着公司转入webgl 我要求调整到osg osgearth工具 因为是c 方面的 特别是osg osgearth源码可以深入下 以前光把视频教程看过 说白了就是简单二次应用 并没有深入下去 所以 趁此机会多读读osg osgearth源码
  • 计算机系统(一)——冯诺依曼体系

    现代计算机的基本结构是由冯诺依曼提出的 冯诺依曼的体系结构体系如下图所示 计算机由运算器 控制器 存储器 也就是内存 输入设备 输出设备五大部件组成 其中运算器和控制器组成cpu 在冯诺依曼体系中 数据先从输入设备输入到内存中 运算时数据从
  • 解决使用SpringBoot上传文件大小受限问题

    今天在做项目学习的过程中 需要用到文件上传 启动项目正常 访问上传post请求突然报出了一个异常 特此记录一下 1 控制台异常 org springframework web multipart MaxUploadSizeExceededE
  • 一起赚美元①

    译者 一只椰子 知识星球链接 https t zsxq com iAiIyfm 本文的主人公叫迈克 他在采访里面提到 自动化工具这一法宝已经轻松帮他实现每个月 12 5万美元的利润 对他而言 年入100万美元 根本不是梦 1 主人公简介 我
  • 看完这篇,成为Grafana高手!

    背景 QQ直播前端团队接入腾讯云前端性能监控 RUM 后 对目前的监控能力以及上报数据进行了梳理 并着手进行了前端性能监控的专项建设 其中监控数据大盘建设是不可或缺的一环 可视化的监控大盘可以清晰明了的观察到各项目运行情况 宏观上能快速进行
  • 【ESP32S2】使用ESP32S2开发板制作U盘,支持无线访问

    文章目录 前言 一 开发环境 二 硬件介绍 三 下载esp idf 四 下载esp iot solution 五 配置idf 1 执行下载脚本 2 设置环境变量 3 声明外部组件 六 构建例程 七 烧写Flash 八 使用方法 九 感谢 前
  • 深度学习之Python,OpenCV中的卷积

    这篇博客将介绍图像内核和卷积 如果将图像视为一个大矩阵 那么图像内核只是一个位于图像顶部的微小矩阵 从左到右和从上到下滑动内核 计算输入图像和内核之间的元素乘法总和 称这个值为内核输出 内核输出存储在与输入图像相同 x y 坐标的输出图像中