博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用python实现对图像的卷积(滤波)
阅读量:5133 次
发布时间:2019-06-13

本文共 2850 字,大约阅读时间需要 9 分钟。

  之前在看卷积神经网络,很好奇卷积到底是什么,最后看到了这篇文章,讲得很清楚,这篇文章中提到了对图像的滤波处理就是对图像应用一个小小的卷积核,并给出了以下例子:

  对图像的卷积,opencv已经有实现的函数filter2D,注意,卷积核需要是奇数行,奇数列,这样才能有一个中心点。opencv卷积的简单实践如下:

import matplotlib.pyplot as pltimport pylabimport cv2import numpy as npimg = plt.imread("apic.jpg")                        #在这里读取图片plt.imshow(img)                                     #显示读取的图片pylab.show()fil = np.array([[ -1,-1, 0],                        #这个是设置的滤波,也就是卷积核                [ -1, 0, 1],                [  0, 1, 1]])res = cv2.filter2D(img,-1,fil)                      #使用opencv的卷积函数plt.imshow(res)                                     #显示卷积后的图片plt.imsave("res.jpg",res)pylab.show()

 

  知道了原理以后,就想自己实现一个简单的卷积,卷积的过程如下,对于mxn的图像,用kxk的滤波依次扫描,扫描的过程就是把原图的矩阵和卷积核依次进行逐点相乘(wise-element)并求和(需要注意求和结果可能大于255或小于0),在讲了卷积的具体过程。

  可以发现一个规律,就是卷积后的图像的大小为(m - k + 1)x(n - k + 1),写代码的时候需要根据这个规律来确定卷积后的图像的大小。

 

 

  根据原理,实现代码如下:

1 import matplotlib.pyplot as plt 2 import pylab 3 import numpy as np 4  5 def convolve(img,fil,mode = 'same'):                #分别提取三个通道 6  7     if mode == 'fill': 8         h = fil.shape[0] // 2 9         w = fil.shape[1] // 210         img = np.pad(img, ((h, h), (w, w),(0, 0)), 'constant')11     conv_b = _convolve(img[:,:,0],fil)              #然后去进行卷积操作12     conv_g = _convolve(img[:,:,1],fil)13     conv_r = _convolve(img[:,:,2],fil)14 15     dstack = np.dstack([conv_b,conv_g,conv_r])      #将卷积后的三个通道合并16     return dstack                                   #返回卷积后的结果17 def _convolve(img,fil):         18     19     fil_heigh = fil.shape[0]                        #获取卷积核(滤波)的高度20     fil_width = fil.shape[1]                        #获取卷积核(滤波)的宽度21     22     conv_heigh = img.shape[0] - fil.shape[0] + 1    #确定卷积结果的大小23     conv_width = img.shape[1] - fil.shape[1] + 124 25     conv = np.zeros((conv_heigh,conv_width),dtype = 'uint8')26     27     for i in range(conv_heigh):28         for j in range(conv_width):                 #逐点相乘并求和得到每一个点29             conv[i][j] = wise_element_sum(img[i:i + fil_heigh,j:j + fil_width ],fil)30     return conv31     32 def wise_element_sum(img,fil):33     res = (img * fil).sum() 34     if(res < 0):35         res = 036     elif res > 255:37         res  = 25538     return res39 40 img = plt.imread("photo.jpg")                        #在这里读取图片41 42 plt.imshow(img)                                     #显示读取的图片43 pylab.show()44 45 46 #卷积核应该是奇数行,奇数列的47 fil = np.array([[-1,-1,-1, 0, 1],48                 [-1,-1, 0, 1, 1],49                 [-1, 0, 1, 1, 1]])50 51 res = convolve(img,fil,'fill')52 print("img shape :" + str(img.shape))53 plt.imshow(res)                                     #显示卷积后的图片54 print("res shape :" + str(res.shape))55 plt.imsave("res.jpg",res)56 pylab.show()

  使用图像水平边缘滤波和浮雕滤波的结果如下,效果和opencv结果一致:

  另外这里也有关于卷积c/c++实现:http://lodev.org/cgtutor/filtering.html 

 

转载于:https://www.cnblogs.com/youmuchen/p/6724780.html

你可能感兴趣的文章
grafana授权公司内部邮箱登录 ldap配置
查看>>
treegrid.bootstrap使用说明
查看>>
[Docker]Docker拉取,上传镜像到Harbor仓库
查看>>
javascript 浏览器类型检测
查看>>
nginx 不带www到www域名的重定向
查看>>
记录:Android中StackOverflow的问题
查看>>
导航,头部,CSS基础
查看>>
[草稿]挂载新硬盘
查看>>
[USACO 2017 Feb Gold] Tutorial
查看>>
关于mysql中GROUP_CONCAT函数的使用
查看>>
OD使用教程20 - 调试篇20
查看>>
Java虚拟机(JVM)默认字符集详解
查看>>
Java Servlet 过滤器与 springmvc 拦截器的区别?
查看>>
(tmp >> 8) & 0xff;
查看>>
linux命令之ifconfig详细解释
查看>>
NAT地址转换
查看>>
Nhibernate 过长的字符串报错 dehydration property
查看>>
Deque - leetcode 【双端队列】
查看>>
gulp插件gulp-ruby-sass和livereload插件
查看>>
免费的大数据学习资料,这一份就足够
查看>>