Python 框模糊不比高斯模糊快吗?

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

我已经编写了一些代码,使用内核卷积对图像应用过滤器。目前,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.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指令、积分图像等。