实验要求:

1)通过调整高斯函数的标准差(sigma)来控制平滑程度;

给定函数:void Gaussian(const MyImage &input, MyImage &output, double sigma);

2)滤波窗口大小取为[6sigma-1]/22+1,[.]表示取整;

3)利用二维高斯函数的行列可分离性进行加速;

先对每行进行一维

实验思路:

1.二维高斯滤波器的生成:模板的中心点是(center, center),根据G(x, y)高斯公式,其他点(i, j)有x = i – center; y = center – j 代入计算。这样求到了模板上每个位置的值,现在是小数。我们可以将模板左上角的像素值 v 乘以 1/v,这样左上角的元素就变为了1。模板的其他元素w也都乘以 1/v即int(w/v),这样所有元素都变为了整数。归一化时除以模板所有元素和就行。

2.一维高斯滤波器的生成也几乎是一样的。行列分离就是用一维高斯滤波器先对行操作,再对列操作,反过来也是一样的。

实验效果:

实验代码:

整个实验代码中包含两个函数Gaussian(未实现行列分离)和SeperateGaussian(实现了行列分离)。

采用行列分离一定要充分利用numpy的特性,否则可能会导致速度下降。以sigma等于1.03为例,Gaussian大约为6.26秒,SeperateGaussian如果仍是逐行逐列去遍历,时间是11秒左右,竟然比未行列分离慢,这显然是不可接受的。通过使用numpy的矩阵乘法,时间下降至0.07秒,如果将k也放入矩阵进行运算时间增加了0.015秒左右,即0.085秒左右。

import cv2 as cv

import numpy as np

def Gaussian(inputImage, outputImage, sigma):

timeBegin = cv.getTickCount()

# 产生二维高斯滤波器kernel,行列不分离

size = int(int(6*sigma-1)//2*2+1) # 高斯滤波器大小为:size x size,size为奇数

kernel = np.zeros([size, size], dtype=np.int)

center = size//2 # 将滤波器分为size x size个小方格,中心点为center,坐标为(0, 0)

normal = 1/(np.exp(-(2*center*center)/(2*(sigma*sigma)))) # 用于整数化

sumAll = 0 # 模板参数总和

for i in range(size):

for j in range(size):

x = i-center # 方格的横坐标

y = center-j # 方格的纵坐标

kernel[i, j] = int(np.exp(-(x*x+y*y)/(2*sigma*sigma)) * normal)

sumAll += kernel[i, j]

# print(kernel[i, j], end=' ') # 打印模板,与下一行共同使用

# print('') # 打印模板,与上一行共同使用

# 对图像inputImage增添

border = center # 需要添加的边界大小

transImage = cv.copyMakeBorder(inputImage, border, border, border, border,

borderType=cv.BORDER_REPLICATE) # 复制最边缘像素

# 开始平滑操作

rows, cols, channels = inputImage.shape

for i in range(rows):

for j in range(cols):

for k in range(channels):

temp = np.sum(np.multiply(transImage[i:i+size, j:j+size, k], kernel)) // sumAll

if temp < 0:

temp = 0

elif temp > 255:

temp = 255

outputImage[i, j, k] = temp

timeEnd = cv.getTickCount()

time = (timeEnd-timeBegin)/cv.getTickFrequency()

return time

def SeperateGaussian(inputImage, outputImage, sigma):

timeBegin = cv.getTickCount()

# 产生一维高斯滤波器kernel,行列分离

size = int(int(6*sigma-1)//2*2+1) # 高斯滤波器大小为:size x size,size为奇数

kernel = np.zeros([size], dtype=np.int)

center = size//2 # 将滤波器分为size x size个小方格,中心点为center,坐标为(0, 0)

normal = 1/(np.exp(-center*center/(2*(sigma*sigma)))) # 用于整数化

sumAll = 0 # 模板参数总和

for i in range(size):

kernel[i] = int(np.exp(-(i-center)*(i-center)/(2*sigma*sigma)) * normal)

sumAll += kernel[i]

#print(kernel[i], end=' ') # 打印模板

kernelRow = kernel

kernelCol = np.resize(kernel, (size, 1))

#print(kernelCol)

# 对图像inputImage增添

border = center # 需要添加的边界大小

transImage = cv.copyMakeBorder(inputImage, border, border, border, border,

borderType=cv.BORDER_REPLICATE) # 复制最边缘像素

# 开始平滑操作

rows, cols, channels = inputImage.shape

# 对行操作

for j in range(cols):

for k in range(channels):

temp = np.sum(np.multiply(transImage[:, j:j+size, k], kernelRow), axis=1) // sumAll

transImage[:, j+border, k] = temp

# 对列操作

for i in range(rows):

for k in range(channels):

temp = np.sum(np.multiply(transImage[i:i + size, border:cols + border, k], kernelCol), axis=0) // sumAll

outputImage[i, :, k] = temp

timeEnd = cv.getTickCount()

time = (timeEnd - timeBegin) / cv.getTickFrequency()

return time

sig = float(input('Please input the value of sigma: '))

print('Please choose the mode of Gaussian: ')

print(' Type 1 if you want to Gaussian')

print(' Type 2 if you want to SeperateGaussian')

print(' Type 3 if yuu want to both')

flag = int(input('The mode is: '))

imgSrc = cv.imread('../images/images2_1/a.jpg') # (481, 641, 3)

imgDst = np.zeros(list(imgSrc.shape), dtype='uint8')

time1 = 0 # 行列不分离的时间

time2 = 0 # 行列分离的时间

time = 0 # 两种方式的时间差

#print(imgSrc.shape)

if flag == 1:

time = Gaussian(imgSrc, imgDst, sig)

elif flag == 2:

time = SeperateGaussian(imgSrc, imgDst, sig)

elif flag == 3:

time1 = Gaussian(imgSrc, imgDst, sig)

time2 = SeperateGaussian(imgSrc, imgDst, sig)

strSigma = 'Gaussian image(sigma: ' + str(sig) + ')'

cv.imshow('source image', imgSrc)

cv.imshow(strSigma, imgDst)

saveSigma = str(sig) + '.png'

cv.imwrite(saveSigma, imgDst)

print("Successful!!!")

if flag == 1 or flag == 2:

print('time(s):', time)

elif flag == 3:

print('time1(s):', time1)

print('time2(s):', time2)

print('time2-time1 =', time2-time1)

cv.waitKey(0)

cv.destroyAllWindows()

opencv python 高斯滤波_Python OpenCV实验(3):实现图像的高斯滤波处理相关推荐

  1. opencv python是什么_Python+OpenCV 十几行代码模仿世界名画

    现在很多人都喜欢拍照(自拍).有限的滤镜和装饰玩多了也会腻,所以就有 APP 提供了模仿名画风格的功能,比如 prisma.versa 等,可以把你的照片变成梵高.毕加索.蒙克等大师的风格. 这种功能 ...

  2. opencv python 调用摄像头_python+opencv实现摄像头调用的方法

    最近入了一块树莓派,想让其实现摄像头的调用,因此写下此博客备忘 一.树莓派网络的配置 首先,对树莓派进行网络配置,否则就无法进行软件的安装 我们知道,ifconfig命令可以修改ip地址.子网掩码等信 ...

  3. 数字图像处理 实验二:图像的平滑滤波

    基于Matlab的图像的平滑滤波 DIP实验2:图像的平滑滤波 实验目的 实验内容 参考代码 实验结果 DIP实验2:图像的平滑滤波 实验目的 平滑的目的是减少噪声对图像的影响.掌握线性滤波和中值滤波 ...

  4. python 视觉技术_python+opencv实现机器视觉基础技术(边缘提取,图像滤波,边缘检测算子,投影,车牌字符分割)...

    机器视觉是人工智能正在快速发展的一个分支.简单说来,机器视觉就是用机器代替人眼来做测量和判断.它是一项综合技术,包括图像处理.机械工程技术.控制.电光源照明.光学成像.传感器.模拟与数字视频技术.计算 ...

  5. python 高斯金字塔_Python OpenCV 之图像金字塔,高斯金字塔与拉普拉斯金字塔

    Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧. 基础知识铺垫 学习图像金字塔,发现网上的资料比较多,检索起来比较轻松. 图像金字塔是一张图像多尺度的表达,或者可以理解成一 ...

  6. python数据挖掘视频_python+opencv实时视频目标检测

    python+opencv实时视频目标检测 opencv环境 1.访问Python Extension Packages for Windows,下载python对应版本的opencv. 比如小编下载 ...

  7. python表面瑕疵检测_python – OpenCV检测水果上的划痕

    对于 Python中的一个小实验我正在做我想要找到水果的小划痕.划痕非常小,很难被人眼检测到. 我正在使用高分辨率相机进行该实验. 这是我想要检测的缺陷: 原始图片: 这是我的结果,只有很少的代码行: ...

  8. opencv python 编译_编译opencv python

    1, 下载并且安装python2.7 + numpy 2,运行cmakegui打开opencv.应该要显示如下信息: Python 2: Interpreter: C:/Python27/python ...

  9. python opencv实时显示测量数据_python OpenCV 宽度测量

    机器视觉第六次实验 一.实验目的 通过OpenCV第六次进行实验,对图片进行宽度测量. 二.实验内容 对图片进行宽度测量. 三.实验过程 我使用的是python语言+openCV对图片进行宽度测量的功 ...

  10. python全景图像拼接_Python+OpenCV实现图像的全景拼接

    本文实例为大家分享了Python+OpenCV实现图像的全景拼接的具体代码,供大家参考,具体内容如下 环境:python3.5.2 + openCV3.4 1.算法目的 将两张相同场景的场景图片进行全 ...

最新文章

  1. Presto日志中出现大量的Triggering GC to avoid Code Cache eviction bugs
  2. 新兴的多媒体格式——MXF 文件格式分析 和简介
  3. Vue页面跳转后不显示问题
  4. 在 PHP 中使用命令行工具
  5. python列表使用判断_浅谈Python数据类型判断及列表脚本操作
  6. java中priorityqueue_详解JAVA中priorityqueue的具体使用
  7. linux 版本号 加号,Linux kernel编译生成的版本多一个加号“+”
  8. vim 保存文件的回车换行模式
  9. Java检查日期格式是否正确
  10. 二维凸包 Graham扫描算法
  11. 【路径规划】基于matlab麻雀算法求解机器人栅格地图最短路径规划问题【含Matlab源码 1582期】
  12. Web开发之Cookie
  13. deepin驱动精灵_解决宏基笔记本没有Qualcomm_Atheros_QCA9377无线驱动
  14. win10 64位 JavaJDK的下载、安装与配置。
  15. 高数_关于e两个重要的积分公式
  16. 编程素人眼里的编程珠玑
  17. C++、Java、JavaScript中回调的用法
  18. IE无法打开internet站点已终止操作的解决办法
  19. React className的写法
  20. python中tkinter较完整的鼠标样式cursor值

热门文章

  1. Java中,类的实例化方法
  2. 《专业嵌入式软件开发》的样章、建议和勘误
  3. C# 反射应用实例-获取当前Color类的所有颜色
  4. Java 理论与实践: 您的小数点到哪里去了?
  5. unity-Profiler调试Android
  6. 计算机c盘要满了电脑会卡吗,C盘满了 电脑卡顿了,怎么清理空间
  7. Android数据存储总结
  8. 数据库得事务控制详解,什么是事务回滚详解,通俗易懂
  9. python 解析模块脚本_Python HTMLParser模块解析html获取url实例
  10. WPF TreeView tools