Python 框模糊不比高斯模糊快吗?
我已经编写了一些代码,使用内核卷积对图像应用过滤器。目前,400x400图像需要相当长的时间,大约30秒。我知道长方体模糊比高斯模糊快得多。然而,当我将内核更改为框模糊时,它似乎需要与高斯模糊一样多的时间。有什么想法吗Python 框模糊不比高斯模糊快吗?,python,opencv,blur,gaussianblur,Python,Opencv,Blur,Gaussianblur,我已经编写了一些代码,使用内核卷积对图像应用过滤器。目前,400x400图像需要相当长的时间,大约30秒。我知道长方体模糊比高斯模糊快得多。然而,当我将内核更改为框模糊时,它似乎需要与高斯模糊一样多的时间。有什么想法吗 import cv2 import numpy as np img = cv2.imread('test.jpg') img2 = cv2.imread('test.jpg') height, width, channels = img.shape GB3 = np.arr
import cv2
import numpy as np
img = cv2.imread('test.jpg')
img2 = cv2.imread('test.jpg')
height, width, channels = img.shape
GB3 = np.array([[1,2,1], [2,4,2], [1,2,1]])
GB5 = np.array([[1,4,6,4,1], [4,16,24,16,4], [6,24,36,24,6], [4,16,24,16,4], [1,4,6,4,1]])
BB = np.array([[1,1,1], [1,1,1], [1,1,1]])
kernel = BB
#initialise
kernel_sum = 1
filtered_sum_r = 0
filtered_sum_g = 0
filtered_sum_b = 0
for i in range(kernel.shape[0]):
for j in range(kernel.shape[1]):
p = kernel[i][j]
kernel_sum += p
for x in range(1,width-1):
for y in range(1,height-1):
for i in range(kernel.shape[0]):
for j in range(kernel.shape[1]):
filtered_sum_b += img[y-1+j,x-1+i,0]*kernel[i][j]
filtered_sum_g += img[y-1+j,x-1+i,1]*kernel[i][j]
filtered_sum_r += img[y-1+j,x-1+i,2]*kernel[i][j]
new_pixel_r = filtered_sum_r/kernel_sum
new_pixel_g = filtered_sum_g/kernel_sum
new_pixel_b = filtered_sum_b/kernel_sum
if new_pixel_r>255:
new_pixel_r = 255
elif new_pixel_r<0:
new_pixel_r = 0
if new_pixel_g>255:
new_pixel_g = 255
elif new_pixel_g<0:
new_pixel_g = 0
if new_pixel_b>255:
new_pixel_b = 255
elif new_pixel_b<0:
new_pixel_b = 0
img2[y,x,0] = new_pixel_b
img2[y,x,1] = new_pixel_g
img2[y,x,2] = new_pixel_r
filtered_sum_r = 0
filtered_sum_g = 0
filtered_sum_b = 0
#print(kernel_sum)
scale = 2
img_big = cv2.resize(img, (0,0), fx=scale, fy=scale)
img2_big = cv2.resize(img2, (0,0), fx=scale, fy=scale)
cv2.imshow('original', img_big)
cv2.imshow('processed', img2_big)
cv2.waitKey(0)
cv2.destroyAllWindows()
导入cv2
将numpy作为np导入
img=cv2.imread('test.jpg')
img2=cv2.imread('test.jpg')
高度、宽度、通道=img.shape
GB3=np.数组([[1,2,1],[2,4,2],[1,2,1]]
GB5=np.数组([[1,4,6,4,1],[4,16,24,16,4],[6,24,36,24,6],[4,16,4],[1,4,6,4,1])
BB=np.数组([[1,1,1],[1,1,1],[1,1,1]]
内核=BB
#初始化
核和=1
过滤的总和=0
过滤的总和=0
过滤的总和=0
对于范围内的i(kernel.shape[0]):
对于范围内的j(kernel.shape[1]):
p=内核[i][j]
核_和+=p
对于范围(1,宽度-1)内的x:
对于范围(1,高度-1)内的y:
对于范围内的i(kernel.shape[0]):
对于范围内的j(kernel.shape[1]):
过滤的_sum_b+=img[y-1+j,x-1+i,0]*内核[i][j]
过滤的μ和μg+=img[y-1+j,x-1+i,1]*内核[i][j]
过滤的_sum _r+=img[y-1+j,x-1+i,2]*内核[i][j]
新的\u像素\u r=过滤的\u和\u r/内核\u和
新的\u像素\u g=过滤的\u和\u g/内核\u和
新的\u像素\u b=过滤的\u和\u b/内核\u和
如果新像素>255:
新像素=255
elif新像素r255:
新像素=255
elif新像素\u g255:
新像素=255
elif新像素\u b
- 您正在使用python循环。这总是比优化的二进制代码慢几个数量级。尽可能使用库函数,即numpy和OpenCV。或者将关键代码编写为可编译的Cython
- 您的代码的访问模式不太理想。您应该沿着内部循环中的行移动(对于y:对于x:),因为这就是图像的存储方式。这里的原因是CPU缓存的使用方式。在中,缓存线在一行中包含多个像素。如果沿着列运行,则在需要另一个缓存线之前只使用该缓存线一次
- 您的代码未使用两种类型的筛选器均为“”的属性
- 卷积可以表示为频域中的元素乘法(DFT、乘法、逆DFT),这是执行卷积的常用方法
使用OpenCV函数进行卷积
至于框模糊和高斯模糊,唯一的区别是“有趣”的权重和没有权重(都相等)。这就意味着再进行几次乘法,或者不进行乘法。当代码被优化时,其执行时间可以由将数据从RAM传输到CPU所需的时间决定。这适用于优化的代码,而不是纯python循环。如果box筛选器具有相同的大小和相同的操作数,则其速度与卷积一样快。长方体过滤器的一个优点是,您可以使用积分图像预计算大量信息,因此可以非常高效地计算较大尺寸的长方体过滤器,并且基本上与过滤器尺寸无关。此外,我想建议您使用opencv函数,而不是自己实现过滤器,因为opencv包含很多优化,如SSE指令、积分图像等。