浅析Python OpenCV三种滤镜效果


Posted in Python onApril 11, 2022

前言

本篇文章要使用OpenCV、Numpy 和Math这3个工具包实现一个简单的滤镜编辑器。在这个滤镜编辑器中,包含了3种滤镜效果,它们分别是浮雕滤镜、雕刻滤镜和凸透镜滤镜。本篇文章将对目标图像(如图1所示)进行处理,使得目标图像分别呈现浮雕滤镜(如图2所示)、雕刻滤镜(如图3所示)和凸透镜滤镜(如图4所示)的视觉效果。

浅析Python OpenCV三种滤镜效果

浅析Python OpenCV三种滤镜效果

浅析Python OpenCV三种滤镜效果

浅析Python OpenCV三种滤镜效果

浮雕滤镜效果

为了实现浮雕滤镜效果,首先要把实现浮雕滤镜效果的原理搞清楚、弄明白。实现浮雕滤镜效果的原理如下所示:

  • 根据灰度图像中的某一个像素的像素值与其周围像素的像素值之间的差值,确定这个像素经过卷积处理后的像素值;

  • 由于边缘点的像素值与其周围像素的像素值之间的差值较大,经卷积处理后,导致这些边缘点较亮,从而达到凸显边缘的目的,进而形成浮雕状;

  • 为经卷积处理后的每一个像素加上一个灰度偏移值128,作为呈现浮雕滤镜效果的图像的底色。

明确了实现浮雕滤镜效果的原理后,再来学习一下实现浮雕滤镜效果的算法。实现浮雕滤镜效果的算法如下所示:

  • 对灰度图像中的每一个像素进行卷积处理;

  • 实现浮雕滤镜效果的卷积核算子需采用如下矩阵:

[[1, 0], [0, -1]]

掌握了实现浮雕滤镜效果的原理和算法后,下面开始编写用于实现浮雕滤镜效果的方法,即fuDiao()方法。fuDiao()方法是一个自定义的、有参且有返回值的方法,fuDiao()方法的语法格式如下所示:

def fuDiao(img):
    ……# 省略方法体中的代码
    return canvas

参数说明:

 img:与目标图像对应的灰度图像。

返回值说明:

canvas:画布,用于呈现浮雕滤镜效果的图像。

那么,fuDiao()方法被省略的代码各自发挥怎样的作用?此外,被省略的代码又是那些呢?

先要明确fuDiao()方法中被省略的代码各自发挥的作用是什么:

因为用于实现浮雕滤镜效果的卷积核算子是一个二维矩阵,所以需要使用Numpy工具包中的array()方法创建这个二维矩阵。关键代码如下所示:

kernel = np.array([[1, 0], [0, -1]])

分别获取灰度图像中像素的行数和列数。关键代码如下所示:

row = img.shape[0]
col = img.shape[1]

根据灰度图像中像素的行数和列数,创建一个等高、等宽的,纯黑色的画布。关键代码如下所示:

canvas = np.zeros([row, col], dtype=np.uint8)

根据横、纵坐标,使用嵌套的for循环得到灰度图像中的每一个像素。关键代码如下所示:

for i in range(row - 1):
for j in range(col - 1):

使用实现浮雕滤镜效果的卷积核算子,对灰度图像中的每一个像素进行卷积处理,并且为经卷积处理后的每一个像素加上一个灰度偏移值128。关键代码如下所示:

new_value = np.sum(img[i:i + 2, j:j + 2] * kernel) + 128

对于经卷积处理且加上一个灰度偏移值后的每一个像素的像素值,如果大于255,那么等于255;如果小于0,那么等于0。关键代码如下所示:

if new_value > 255:
   new_value = 255
   elif new_value < 0:
      new_value = 0
  else:
    pass

把经过比较后的每一个像素的像素值根据坐标赋值给画布对应位置上的像素。关键代码如下所示:

canvas[i, j] = new_value

结合fuDiao()方法中被省略的代码和它们各自发挥的作用,就能够迅速完成fuDiao()方法的编写。fuDiao()方法的代码如下所示:

def fuDiao(img):
      kernel = np.array([[1, 0], [0, -1]])
      row = img.shape[0]
      col = img.shape[1]
      canvas = np.zeros([row, col], dtype=np.uint8)
      for i in range(row - 1):
         for j in range(col - 1):
             new_value = np.sum(img[i:i + 2, j:j + 2] * kernel) + 128
             if new_value > 255:
                 new_value = 255
              elif new_value < 0:
                 new_value = 0
              else:
                  pass
             canvas[i, j] = new_value
      return canvas

雕刻滤镜效果

实现雕刻滤镜效果的原理与实现浮雕滤镜效果的原理大致相同,实现雕刻滤镜效果的原理如下所示:

  • 根据灰度图像中的某一个像素的像素值与其周围像素的像素值之间的差值,确定这个像素经过卷积处理后的像素值;

  • 由于边缘点的像素值与其周围像素的像素值之间的差值较大,经卷积处理后,导致这些边缘点较暗,从而达到凹陷边缘的目的,进而形成雕刻状;

  • 为经卷积处理后的每一个像素加上一个灰度偏移值128,作为呈现雕刻滤镜效果的图像的底色。

虽然实现雕刻滤镜效果的原理与实现浮雕滤镜效果的原理大致相同,但是实现雕刻滤镜效果的算法与实现浮雕滤镜效果的算法大不相同。实现雕刻滤镜效果的算法如下所示:

  • 对灰度图像中的每一个像素进行卷积处理;

  • 实现雕刻滤镜效果的卷积核算子需采用如下矩阵:

[[-1, 0],
[0, 1]]

掌握了实现雕刻滤镜效果的原理和算法后,下面开始编写用于实现雕刻滤镜效果的方法,即diaoKe()方法。与fuDiao()方法相同,diaoKe()方法也是一个自定义的、有参且有返回值的方法,diaoKe()方法的语法格式如下所示:

def diaoKe(img):
   ……# 省略方法体中的代码
    return canvas

参数说明:

img:与目标图像对应的灰度图像。

返回值说明:

canvas:画布,用于呈现雕刻滤镜效果的图像。

diaoKe()方法被省略的代码与fuDiao()方法被省略的代码大同小异,首先明确下diaoKe()方法中被省略的代码各自发挥的作用是什么:

用于实现雕刻滤镜效果的卷积核算子与用于实现浮雕滤镜效果的卷积核算子虽然不同,但也是一个二维矩阵,因此需要使用Numpy工具包中的array()方法创建这个二维矩阵。关键代码如下所示:

kernel = np.array([[-1, 0], [0, 1]])

分别获取灰度图像中像素的行数和列数。关键代码如下所示:

row = img.shape[0]
col = img.shape[1]

根据灰度图像中像素的行数和列数,创建一个等高、等宽的,纯黑色的画布。关键代码如下所示:

canvas = np.zeros([row, col], dtype=np.uint8)

根据横、纵坐标,使用嵌套的for循环得到灰度图像中的每一个像素。关键代码如下所示:

for i in range(row - 1):
for j in range(col - 1):

使用实现雕刻滤镜效果的卷积核算子,对灰度图像中的每一个像素进行卷积处理,并且为经卷积处理后的每一个像素加上一个灰度偏移值128。关键代码如下所示:

new_value = np.sum(img[i:i + 2, j:j + 2] * kernel) + 128

对于经卷积处理且加上一个灰度偏移值后的每一个像素的像素值,如果大于255,那么等于255;如果小于0,那么等于0。关键代码如下所示:

if new_value > 255:
      new_value = 255
  elif new_value < 0:
      new_value = 0
  else:
      pass

把经过比较后的每一个像素的像素值根据坐标赋值给画布对应位置上的像素。关键代码如下所示:

canvas[i, j] = new_value

结合diaoKe()方法中被省略的代码和它们各自发挥的作用,就能够迅速完成diaoKe()方法的编写。diaoKe()方法的代码如下所示:

def diaoKe(img):
      kernel = np.array([[-1, 0], [0, 1]])
      row = img.shape[0]
      col = img.shape[1]
      canvas = np.zeros([row, col], dtype=np.uint8)
      for i in range(row - 1):
          for j in range(col - 1):
              new_value = np.sum(img[i:i + 2, j:j + 2] * kernel) + 128
              if new_value > 255:
                  new_value = 255
              elif new_value < 0:
                  new_value = 0
              else:
                  pass
              canvas[i, j] = new_value
      return canvas

凸透镜滤镜效果

所谓凸透镜滤镜效果,相当于用户使用凸透镜观察一幅图像而成的视觉效果。实现凸透镜滤镜效果的原理与实现浮雕滤镜效果的原理和实现雕刻滤镜效果的原理大不相同。下面将着重对实现凸透镜滤镜效果的原理进行讲解:

  • 当使用凸透镜中心观察一幅图像时,被观察的图像区域将按照一定比例进行放大;相应地,这个区域的周围区域将被压缩;

  • 为了让放大后的图像区域看起来和谐自然,这些被压缩的周围区域要保持连续性。

明确了实现凸透镜滤镜效果的原理后,再来学习一下实现凸透镜滤镜效果的算法。实现凸透镜滤镜效果的算法如下所示:

  • 根据目标图像的宽、高确定凸透镜的半径;

  • 选择一个凸函数作为映射函数;

如果目标图像中的某一个像素与目标图像中心之间的距离的平方不大于凸透镜的半径的平方(两个整数进行比较,保证比较结果的精确度),就使用映射函数对这个像素的横、纵坐标进行映射处理。

掌握了实现凸透镜滤镜效果的原理和算法后,下面开始编写用于实现凸透镜滤镜效果的方法,即tuTouJing()方法。与fuDiao()方法和diaoKe()方法相同,tuTouJing()方法也是一个自定义的、有参且有返回值的方法,tuTouJing()方法的语法格式如下所示:

def tuTouJing(img):
    ……# 省略方法体中的代码
    return canvas

参数说明:

 img:目标图像。

返回值说明:

canvas:画布,用于呈现凸透镜滤镜效果的图像。

先要明确tuTouJing()方法中被省略的代码各自发挥的作用是什么:

分别获取目标图像中像素的行数和列数以及目标图像的通道数。关键代码如下所示:

row = img.shape[0]
col = img.shape[1]
channel = img.shape[2]

根据目标图像中像素的行数和列数以及目标图像的通道数,创建一个等高、等宽、等通道数的,纯黑色的画布。关键代码如下所示:

canvas = np.zeros([row, col, channel], dtype=np.uint8)

根据目标图像中像素的行数和列数,分别获取目标图像中心的横、纵坐标。关键代码如下所示:

center_x = row/2
center_y = col/2

比较目标图像中心的横、纵坐标的大小,把较小的数值作为凸透镜的半径。关键代码如下所示:

radius = min(center_x, center_y)

根据横、纵坐标,使用嵌套的for循环得到目标图像中的每一个像素。关键代码如下所示:

for i in range(row):
for j in range(col):

计算目标图像中的每一个像素与目标图像中心之间的距离的平方和距离。关键代码如下所示:

distance = ((i-center_x) * (i-center_x) + (j-center_y) * (j-center_y))
new_dist = math.sqrt(distance)

把目标图像中的每一个像素的像素值根据坐标赋值给画布对应位置上的像素。关键代码如下所示:

canvas[i,j,:] = img[i, j, :]

如果目标图像中的某一个像素与目标图像中心之间的距离的平方不大于凸透镜的半径的平方,就使用映射函数对这个像素的横、纵坐标进行映射处理。关键代码如下所示:

if distance <= radius**2:
new_i = np.int(np.floor(new_dist * (i-center_x) / radius + center_x))
new_j = np.int(np.floor(new_dist * (j-center_y) / radius + center_y))

把经过映射处理后的每一个像素的像素值根据坐标赋值给画布对应位置上的像素。关键代码如下所示:

canvas[i,j,:] = img[new_i, new_j, :]

结合tuTouJing()方法中被省略的代码和它们各自发挥的作用,就能够迅速完成tuTouJing()方法的编写。tuTouJing()方法的代码如下所示:

def tuTouJing(img):
      row = img.shape[0]
      col = img.shape[1]
      channel = img.shape[2]
      canvas = np.zeros([row, col, channel], dtype=np.uint8)
      center_x = row/2
      center_y = col/2
      radius = min(center_x, center_y)
      for i in range(row):
          for j in range(col):
              distance = ((i-center_x) * (i-center_x) + (j-center_y) * (j-center_y))
              new_dist = math.sqrt(distance)
              canvas[i,j,:] = img[i, j, :]
              if distance <= radius**2:
                  new_i = np.int(np.floor(new_dist * (i-center_x) / radius + center_x))
                  new_j = np.int(np.floor(new_dist * (j-center_y) / radius + center_y))
                  canvas[i,j,:] = img[new_i, new_j, :]
      return canvas
Python 相关文章推荐
python测试驱动开发实例
Oct 08 Python
Python发送以整个文件夹的内容为附件的邮件的教程
May 06 Python
Python实现简单HTML表格解析的方法
Jun 15 Python
Python判断直线和矩形是否相交的方法
Jul 14 Python
详解python上传文件和字符到PHP服务器
Nov 24 Python
Python+selenium实现自动循环扔QQ邮箱漂流瓶
May 29 Python
Python 脚本实现淘宝准点秒杀功能
Nov 13 Python
Tensorflow累加的实现案例
Feb 05 Python
TensorFlow keras卷积神经网络 添加L2正则化方式
May 22 Python
Python爬取网页信息的示例
Sep 24 Python
Pytorch之扩充tensor的操作
Mar 04 Python
python中的class_static的@classmethod的巧妙用法
Jun 22 Python
实战Python爬虫爬取酷我音乐
用PYTHON去计算88键钢琴的琴键频率和音高
python图像处理 PIL Image操作实例
Apr 09 #Python
Python Pytorch查询图像的特征从集合或数据库中查找图像
Python实现科学占卜 让视频自动打码
Python自动化工具之实现Excel转Markdown表格
Python加密技术之RSA加密解密的实现
Apr 08 #Python
You might like
PHP 编写的 25个游戏脚本
2009/05/11 PHP
PHP数据集构建JSON格式及新数组的方法
2012/11/07 PHP
PHP微信H5支付开发实例
2018/07/25 PHP
飞鱼(shqlsl) javascript作品集
2006/12/16 Javascript
让回调函数 showResponse 也带上参数的代码
2007/08/13 Javascript
javascript版2048小游戏
2015/03/18 Javascript
微信小程序微信支付接入开发实例详解
2017/04/12 Javascript
SVG动画vivus.js库使用小结(实例代码)
2017/09/14 Javascript
AngularJS实现的select二级联动下拉菜单功能示例
2017/10/25 Javascript
React Native 真机断点调试+跨域资源加载出错问题的解决方法
2018/01/18 Javascript
原生js实现html手机端城市列表索引选择城市
2020/06/24 Javascript
vue抽出组件并传值实例
2020/07/31 Javascript
OpenLayers3加载常用控件使用方法详解
2020/09/25 Javascript
Django中对通过测试的用户进行限制访问的方法
2015/07/23 Python
django连接mysql配置方法总结(推荐)
2018/08/18 Python
python多个模块py文件的数据共享实例
2019/01/11 Python
使用selenium模拟登录解决滑块验证问题的实现
2019/05/10 Python
详解CSS3的opacity属性设置透明效果的用法
2016/05/09 HTML / CSS
HTML5拖放效果的实现代码
2016/11/17 HTML / CSS
施华洛世奇加拿大官网:SWAROVSKI加拿大
2018/06/03 全球购物
个性化皮包、小袋、生活配件:Mon Purse
2019/03/26 全球购物
Deichmann英国:德国鞋类零售商
2021/01/30 全球购物
初中校园之声广播稿
2014/01/15 职场文书
幼儿园元旦家长感言
2014/02/27 职场文书
空乘英文求职信
2014/04/13 职场文书
大班幼儿评语大全
2014/04/30 职场文书
标准毕业生自荐信
2014/06/24 职场文书
三八妇女节标语
2014/10/09 职场文书
免职证明样本
2014/10/23 职场文书
2014年监理工作总结范文
2014/11/17 职场文书
暑假安全保证书
2015/02/28 职场文书
大学生自荐书范文
2015/03/05 职场文书
审美与表现自我评价
2015/03/09 职场文书
公文写作:工伤事故分析报告怎么写?
2019/11/05 职场文书
springboot读取nacos配置文件
2022/05/20 Java/Android
python playwrigh框架入门安装使用
2022/07/23 Python