python sobel滤波_python - 如何提高sobel边缘检测器的效率 - 堆栈内存溢出
即使您正在构建自己的库,您也绝对应该使用库进行卷积,它们将在后端用C或Fortran进行结果运算,这将大大加快速度。
但是,如果您愿意,可以自己做,使用线性可分离滤波器。 这是想法:
图片:
1 2 3 4 5
2 3 4 5 1
3 4 5 1 2
Sobel x内核:
-1 0 1
-2 0 2
-1 0 1
结果:
8, 3, -7
在卷积的第一个位置,您将计算9个值。 首先,为什么? 您永远不会添加中间列,不必费心将其相乘。 但这不是线性可分离滤波器的重点。 这个想法很简单。 将内核放在第一个位置时,会将第三列乘以[1, 2, 1] 。 但是随后的两个步骤,您将第三列乘以[-1, -2, -1] 。 真是浪费! 您已经计算过了,现在只需要取反即可。 这就是线性可分离滤波器的想法。 请注意,您可以将过滤器分解为两个向量的矩阵外积:
[1]
[2] * [-1, 0, 1]
[1]
将外部乘积在这里得到相同的矩阵。 因此,这里的想法是将操作分为两部分。 首先将整个图像乘以行向量,然后乘以列向量。 以行向量
-1 0 1
在整个图像上,我们最终得到
2 2 2
2 2 -3
2 -3 -3
然后将列向量传递给乘法和求和,我们再次得到
8, 3, -7
另一种可能有用或无效的妙招(取决于您在内存和效率之间的权衡):
请注意,在单行乘法中,您忽略中间值,而只从左边的值中减去右边的值。 这意味着您正在有效地执行以下操作减去这两个图像:
3 4 5 1 2 3
4 5 1 - 2 3 4
5 1 2 3 4 5
如果将图像的前两列剪掉,则会得到左矩阵,如果将后两列剪掉,则会得到右矩阵。 因此,您只需将卷积的第一部分计算为
result_h = img[:,2:] - img[:,:-2]
然后,您可以遍历sobel运算符的其余列。 或者,您甚至可以继续进行,然后做我们刚才做的相同的事情。 这次是垂直情况,您只需要添加第一行和第三行,第二行加倍即可; 或者,使用numpy加法:
result_v = result_h[:-2] + result_h[2:] + 2*result_h[1:-1]
大功告成! 我可能会在不久的将来在此处添加一些时间。 对于包络的某些计算(例如,在1000x1000图像上草草的Jupyter笔记本计时):
新方法(图像总和):每个循环8.18 ms±399 µs(平均±标准偏差,共运行7次,每个循环100个)
旧方法(双循环):每个循环7.32 s±207毫秒(平均±标准偏差,共运行7次,每个循环1次)
是的,您没看错:1000倍加速。
这是比较两者的一些代码:
import numpy as np
def sobel_x_orig(img):
xKernel = np.array([[-1,0,1],[-2,0,2],[-1,0,1]])
sobelled = np.zeros((img.shape[0]-2, img.shape[1]-2))
for y in range(1, img.shape[0]-1):
for x in range(1, img.shape[1]-1):
sobelled[y-1, x-1] = np.sum(np.multiply(img[y-1:y+2, x-1:x+2], xKernel))
return sobelled
def sobel_x_new(img):
result_h = img[:,2:] - img[:,:-2]
result_v = result_h[:-2] + result_h[2:] + 2*result_h[1:-1]
return result_v
img = np.random.rand(1000, 1000)
sobel_new = sobel_x_new(img)
sobel_orig = sobel_x_orig(img)
assert (np.abs(sobel_new-sobel_orig) < 1e-12).all()
当然, 1e-12容忍度很严格,但这是1e-12每个元素的,因此应该可以。 但是我还有一个float图像,对于uint8图像,您当然会有更大的差异。
请注意,您可以对任何线性可分离滤波器执行此操作! 包括高斯滤波器。 还要注意,通常,这需要很多操作。 在C或Fortran或任何其他语言中,通常仅将其实现为单行/列向量的两个卷积,因为最后,它实际上仍然需要遍历每个矩阵的每个元素; 不管您是将它们相加还是相乘,因此在C中用这种方法添加图像值并不比卷积要快。 但是遍历numpy数组非常慢,因此在Python中这种方法要快得多。
python sobel滤波_python - 如何提高sobel边缘检测器的效率 - 堆栈内存溢出相关推荐
- python多个摄像头_python - 使用python和OpenCV与VideoCapture洞察多个网络摄像头捕获 - 堆栈内存溢出...
我正在尝试同时(或几乎同时)从多个网络摄像头捕获图像. 我一直在玩OpenCV ,使用VideoCapture和python编程. 但有一些困惑,希望有人可以帮助解释事情...... 首先,我尝试了V ...
- python堆栈反向输出列表_python - IPython:将Python脚本的输出重定向到文件(如bash) - 堆栈内存溢出...
IPython有自己的上下文管理器来捕获stdout / err ,但它没有重定向到文件,它重定向到一个对象: from IPython.utils import io with io.capture ...
- python协方差矩阵_python - 使用pandas.ewm.cov的EWMA协方差矩阵 - 堆栈内存溢出
我正在尝试使用函数pandas.ewm.cov()计算一组数据之间的指数加权协方差. 听起来很傻,但我无法访问结果:特别是如何获取最后一个矩阵(在本例中为第999个)作为pandas数据帧(切片等似乎 ...
- python 均值滤波_Python的一个骚操作
PS作为世界四大发明之一可以说被广大网友用到了极致,只有你想不到的没有我P不了的,任何正经的图片在都可以变成搞笑图片(比如下图)当然也可以用ps做一点正经的事情. 作为一个爱折腾的程序猿能用代码的解决 ...
- python异常数据处理_Python爬虫提高之异常处理
Python爬虫框架之异常处理 任何访问服务器获取数据的请求,都需要做异常处理,当然爬虫更需要我们对各种异常进行处理.只有这样才能提高爬虫的健壮性.如果我们的爬虫足够健壮,那么就能确保程序几个月不停止 ...
- python示波器 波形数据_python - 将示波器的VISA波形导入Python - 堆栈内存溢出
我从此VISA收购电话获得的返回结果有问题: ribData = [] ribData = inst.query('CURVe?') 我正在使用此呼叫从示波器获取波形. 我正在用Python开发该程序 ...
- python编写数学公式大全_python - 用python编写数学公式 - 堆栈内存溢出
我正在用python编写此公式. 请查看图片我正在使用以下代码. 它总是会出错. import math import matplotlib matplotlib.use('TkAgg') from ...
- python 堆栈溢出_python - 使用CFFI释放内存时,“ MemoryError:堆栈溢出”是什么意思? - 堆栈内存溢出...
这一个问题, 这一个 . 我使用CFFI创建DLL,并从C ++应用程序中调用它. 我在问自己如何找到释放由DLL分配的内存的方法,我遵循@metal在其答案中提到的想法. 现在是我的Python代码 ...
- c与python内存传递_python - 从Python向C ++传递COM指针数组 - 堆栈内存溢出
我已经阅读了许多文档,示例和StackOverflow主题,但仍然无法正常工作! 我正在为我的C ++ COM对象编写一个Python接口. 这不是我第一次这样做. 过去,我已经成功地使用comtyp ...
最新文章
- OpenCV中导向滤波介绍与应用
- 怎么理解java面向对象_Java 面向对象理解?
- 由于Eclipse版本不符造成的异常
- Cocos2d学习之路三(使用Zwoptex创建精灵表单和CCAnimate动画)
- 伺服步进电机选型软件_关于伺服步进电机的28个问题
- php图书信息浏览器,使PHP即时输出结果到浏览器
- Linux下编写选择排序(C语言)
- 在Docker中运行SpringBoot程序
- CentOS ASP.NET Core Runtime Jexus跨平台布署
- 百度 java基础_java基础知识点整理
- 深入理解 sudo 与 su 之间的区别【转】
- java sql loader_Oracle的存储过程中如何调用sql loader?
- 如何对CAD中的曲线进行测量?
- 终于找到可转载的摄影基础知识贴了
- 武汉大花岭科目二考试说明
- Sharepoint visio Web Access
- 抓铁有力榜:踏石有印,抓铁留痕
- DSP入门小白学习日记第三篇
- 利用贝叶斯算法对垃圾邮件进行分类处理
- AR AP 重分类和操作 转