python——对图像进行卷积操作,使用多个滤波器
线性滤波可以说是图像处理最基本的方法,它可以允许我们对图像进行处理,产生很多不同的效果。做法很简单。首先,我们有一个二维的滤波器矩阵(有个高大上的名字叫卷积核)和一个要处理的二维图像。然后,对于图像的每一个像素点,计算它的邻域像素和滤波器矩阵的对应元素的乘积,然后加起来,作为该像素位置的值。这样就完成了滤波过程。
对图像和滤波矩阵进行逐个元素相乘再求和的操作就相当于将一个二维的函数移动到另一个二维函数的所有位置,这个操作就叫卷积或者协相关。卷积和协相关的差别是,卷积需要先对滤波矩阵进行180的翻转,但如果矩阵是对称的,那么两者就没有什么差别了。
Correlation 和 Convolution可以说是图像处理最基本的操作,但却非常有用。这两个操作有两个非常关键的特点:它们是线性的,而且具有平移不变性shift-invariant。平移不变性指我们在图像的每个位置都执行相同的操作。线性指这个操作是线性的,也就是我们用每个像素的邻域的线性组合来代替这个像素。这两个属性使得这个操作非常简单,因为线性操作是最简单的,然后在所有地方都做同样的操作就更简单了。
实际上,在信号处理领域,卷积有广泛的意义,而且有其严格的数学定义,但在这里不关注这个。
2D卷积需要4个嵌套循环4-double loop,所以它并不快,除非我们使用很小的卷积核。这里一般使用3x3或者5x5。而且,对于滤波器,也有一定的规则要求:
1)滤波器的大小应该是奇数,这样它才有一个中心,例如3x3,5x5或者7x7。有中心了,也有了半径的称呼,例如5x5大小的核的半径就是2。
2)滤波器矩阵所有的元素之和应该要等于1,这是为了保证滤波前后图像的亮度保持不变。当然了,这不是硬性要求了。
3)如果滤波器矩阵所有元素之和大于1,那么滤波后的图像就会比原图像更亮,反之,如果小于1,那么得到的图像就会变暗。如果和为0,图像不会变黑,但也会非常暗。
4)对于滤波后的结构,可能会出现负数或者大于255的数值。对这种情况,我们将他们直接截断到0和255之间即可。对于负数,也可以取绝对值。
常见的卷积核:
soble_x = np.array(([-1, 0, 1], [-2, 0, 2], [-1, 0, 1]))
soble_y = np.array(([-1, -2, -1], [0, 0, 0], [1, 2, 1]))
soble = np.array(([-1, -1, 0], [-1, 0, 1], [0, 1, 1]))
prewitt_x = np.array(([-1, 0, 1], [-1, 0, 1], [-1, 0, 1]))
prewitt_y = np.array(([-1, -1,-1], [0, 0, 0], [1, 1, 1]))
prewitt = np.array(([-2, -1, 0], [-1, 0, 1], [0, 1, 2]))
laplacian = np.array(([0, -1, 0], [-1, 4, -1], [0, -1, 0]))
laplacian2 = np.array(([-1, -1, -1], [-1, 8, -1], [-1, -1, -1]))
不同的卷积核对图像进行滤波得到的效果是不同的,我们可以根据滤波器的特点分析出滤波器的功能,下面我们使用python代码对卷积操作进行实践:
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib as mpl def convolve(image, filt):
height, width = image.shape
h, w = filt.shape
height_new = height - h + 1
width_new = width - w + 1
image_new = np.zeros((height_new, width_new), dtype=np.float)
for i in range(height_new):
for j in range(width_new):
image_new[i,j] = np.sum(image[i:i+h, j:j+w] * filt)
image_new = image_new.clip(0, 255)
image_new = np.rint(image_new).astype('uint8')
return image_new if __name__ == "__main__":
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False path = './simplepython/convolve/lena.png'
A = Image.open(path, 'r')
a = np.array(A)
soble_x = np.array(([-1, 0, 1], [-2, 0, 2], [-1, 0, 1]))
soble_y = np.array(([-1, -2, -1], [0, 0, 0], [1, 2, 1]))
soble = np.array(([-1, -1, 0], [-1, 0, 1], [0, 1, 1]))
prewitt_x = np.array(([-1, 0, 1], [-1, 0, 1], [-1, 0, 1]))
prewitt_y = np.array(([-1, -1,-1], [0, 0, 0], [1, 1, 1]))
prewitt = np.array(([-2, -1, 0], [-1, 0, 1], [0, 1, 2]))
laplacian = np.array(([0, -1, 0], [-1, 4, -1], [0, -1, 0]))
laplacian2 = np.array(([-1, -1, -1], [-1, 8, -1], [-1, -1, -1]))
weight_list = ('soble_x', 'soble_y', 'soble', 'prewitt_x', 'prewitt_y', 'prewitt', 'laplacian', 'laplacian2')
plt.figure(figsize=(10,4))
i = 1
for weight in weight_list:
R = convolve(a[:, :, 0], eval(weight))
G = convolve(a[:, :, 1], eval(weight))
B = convolve(a[:, :, 2], eval(weight))
I = 255 - np.stack((R, G, B), 2) plt.subplot(2, 4, i)
i += 1
plt.title("滤波器: %s"%(weight))
plt.axis('off')
plt.imshow(I)
plt.tight_layout(2)
plt.subplots_adjust(top=0.92)
plt.suptitle('不同的图像卷积操作')
plt.show()
上述代码中,image_new.clip(0, 255)函数的作用是将image_new中的值进行截断,小于等于0的置为0,大于等于255的置为255。np.rint(image_new).astype('uint8')的含义是将得到的图像矩阵转换为int型,在转换为uint8类型。eval(weight)函数的作用是将字符串值转换为对应的变量值。我们对lena图像进行操作,下面是得到的结果:
python——对图像进行卷积操作,使用多个滤波器的更多相关文章
- 用python实现对图像的卷积(滤波)
之前在看卷积神经网络,很好奇卷积到底是什么,最后看到了这篇文章http://blog.csdn.net/zouxy09/article/details/49080029,讲得很清楚,这篇文章中提到了对 ...
- 对抗生成网络-图像卷积-mnist数据生成(代码) 1.tf.layers.conv2d(卷积操作) 2.tf.layers.conv2d_transpose(反卷积操作) 3.tf.layers.batch_normalize(归一化操作) 4.tf.maximum(用于lrelu) 5.tf.train_variable(训练中所有参数) 6.np.random.uniform(生成正态数据
1. tf.layers.conv2d(input, filter, kernel_size, stride, padding) # 进行卷积操作 参数说明:input输入数据, filter特征图的 ...
- Python机器学习笔记:卷积神经网络最终笔记
这已经是我的第四篇博客学习卷积神经网络了.之前的文章分别是: 1,Keras深度学习之卷积神经网络(CNN),这是开始学习Keras,了解到CNN,其实不懂的还是有点多,当然第一次笔记主要是给自己心中 ...
- ubuntu之路——day17.1 卷积操作的意义、边缘检测的示例、filter与padding的关系、卷积步长
感谢吴恩达老师的公开课,以下图片均来自于吴恩达老师的公开课课件 为什么要进行卷积操作? 我们通过前几天的实验已经做了64*64大小的猫图片的识别. 在普通的神经网络上我们在输入层上输入的数据X的维数为 ...
- ubuntu之路——day17.2 RGB图像的卷积、多个filter的输出、单个卷积层的标记方法
和单层图像的卷积类似,只需要对每一个filter构成的三层立方体上的每一个数字与原图像对应位置的数字相乘相加求和即可. 在这个时候可以分别设置filter的R.G.B三层,可以同时检测纵向或横向边缘, ...
- 【Python | opencv+PIL】常见操作(创建、添加帧、绘图、读取等)的效率对比及其优化
一.背景 本人准备用python做图像和视频编辑的操作,却发现opencv和PIL的效率并不是很理想,并且同样的需求有多种不同的写法并有着不同的效率.见全网并无较完整的效率对比文档,遂决定自己丰衣足食 ...
- ICLR 2020 | 抛开卷积,multi-head self-attention能够表达任何卷积操作
近年来很多研究将nlp中的attention机制融入到视觉的研究中,得到很不错的结果,于是,论文侧重于从理论和实验去验证self-attention可以代替卷积网络独立进行类似卷积的操作,给self- ...
- 比CNN表现更好,CV领域全新卷积操作OctConv厉害在哪里?
CNN卷积神经网络问世以来,在计算机视觉领域备受青睐,与传统的神经网络相比,其参数共享性和平移不变性,使得对于图像的处理十分友好,然而,近日由Facebook AI.新家坡国立大学.360人工智能研究 ...
- python 文件及文件夹操作
python 文件.目录操作(新增.移动.删除等) python 文件夹与文件操作 mport string, os, sys dir = '/var' print '----------- no s ...
随机推荐
- Ubuntu16.04下安装Hadoop
一.记录理由 刚开始只是想要学习怎么使用Hive的.想着安装应该很简单,没想到花了整整一天的时间来安装,为了避免下次犯同样的错误,特此记录. 二.安装Hadoop 网上教你怎么安装Hadoop的文章有 ...
- python爬虫入门(三)XPATH和BeautifulSoup4
XML和XPATH 用正则处理HTML文档很麻烦,我们可以先将 HTML文件 转换成 XML文档,然后用 XPath 查找 HTML 节点或元素. XML 指可扩展标记语言(EXtensible Ma ...
- 网络-tcp
1.TCP:面向连接可靠的传输协议,全拼:Transmission Control Protocol 2.UDP:用户数据报协议 全拼:User Datagram protocol 不是面向连接的 ...
- Python:怎样用线程将任务并行化?
如果待处理任务满足: 可拆分,即任务可以被拆分为多个子任务,或任务是多个相同的任务的集合: 任务不是CPU密集型的,如任务涉及到较多IO操作(如文件读取和网络数据处理) 则使用多线程将任务并行运行,能 ...
- 十九、Hadoop学记笔记————Hbase和MapReduce
概要: hadoop和hbase导入环境变量: 要运行Hbase中自带的MapReduce程序,需要运行如下指令,可在官网中找到: 如果遇到如下问题,则说明Hadoop的MapReduce没有权限访问 ...
- JQUERY获取loaded 宽高这么变态
JQUERY获取loaded 宽高这么变态: $('<img/>').attr('src',img.src).load(function() { img.Owidth = $(this). ...
- Markdown 编辑器语法 专题
基本技巧 代码 如果你只想高亮语句中的某个函数名或关键字,可以使用 `function_name()` 实现 通常编辑器根据代码片段适配合适的高亮方法,但你也可以用 ```(tab键上的符号,要从每行 ...
- Mybatis通过注解方式实现批量插入数据库 及 常见的坑
原文地址:http://f0rb.iteye.com/blog/1207384 MyBatis中通过xml文件配置数据库批量操作的文章很多,比如这篇http://www.cnblogs.com/xcc ...
- SVN使用教程2017.10.6
http://www.cnblogs.com/mq0036/p/5250198.html
- dom操作相关,byebye T T
o = { name: 'aa', price: 11, } function add(items) { var bodys = document.getElementsByTagName('tbod ...