如何提升DM-Script高斯模糊效率,缩小与Python SciPy的性能差距
DM-Script高斯模糊性能优化方案
我用以下DM-Script代码生成高斯模糊图像,处理4K图像耗时约2秒,但Python SciPy的类似操作仅需0.5秒。
原DM-Script代码:
Image gaussian_conv(Image src_img, Number std_dev) { // Use the Warp function to stretch the image to fit into the revised dimensions number src_img_sx, src_img_sy src_img.GetSize(src_img_sx, src_img_sy) Image warp_img = RealImage("", 4, src_img_sx, src_img_sy) warp_img = Warp(src_img, icol * src_img_sx / src_img_sx, irow * src_img_sy / src_img_sy) // Create the gaussian kernel using the same dimensions as the srced image Image kernel_img := RealImage("", 4, src_img_sx, src_img_sy) Number xmidpoint = src_img_sx / 2 Number ymidpoint = src_img_sy / 2 kernel_img = 1 / (2*pi() * std_dev ** 2) * exp(-1 * (((icol - xmidpoint) ** 2 + (irow - ymidpoint) ** 2)/(2 * std_dev ** 2))) // Carry out the convolution in Fourier space ComplexImage fft_kernel_img := RealFFT(kernel_img) ComplexImage fft_src_img := RealFFT(warp_img) ComplexImage fft_product_img := fft_src_img * fft_kernel_img.modulus().sqrt() RealImage invFFT := RealIFFT(fft_product_img) // Warp the convoluted image back to the original size Image filter = RealImage("", 4, src_img_sx, src_img_sy) filter = Warp(invFFT, icol / src_img_sx * src_img_sx, irow / src_img_sy * src_img_sy) return filter } Image img := get_front_img() Number std_dev String prompt = "Input standard deviation. 0=no blurring, 1=minimal blurring, 3=mild blurring, 10=severe blurring" GetNumber(prompt, 3, std_dev) Number time1, time2 time1 = GetCurrentTime() Image blurred_img := gaussian_conv(img, std_dev) time2 = GetCurrentTime() Result(CalcTimeUnitsBetween(time1, time2, 1) + "\n") blurred_img.ShowImage()
对比的Python代码:
import DigitalMicrograph as DM import scipy.ndimage.filters as sfilt import time img = DM.GetFrontImage() img_np = img.GetNumArray() start=time.perf_counter() img1_np = sfilt.gaussian_filter(img_np, 3) end=time.perf_counter() print("Processing Time= "+str(end-start)) img1 = DM.CreateImage(img1_np) img1.ShowImage()
已尝试操作:
- 对比Python SciPy包性能,确认其速度更快;
- 查阅DM-Script文档,未找到性能优化设置。
问题:
- 在DM-Script中,是否有更优方法或替代方案可提升高分辨率图像的高斯模糊效率?
- 通过调整参数或使用不同算法,能否在DM-Script中实现性能提升?
优化方案
1. 直接使用DM内置高斯模糊函数(最优选择)
DM内置的GaussianBlur()函数是底层优化实现的,性能远超手动编写的代码,处理4K图像的耗时可接近SciPy水平。
优化后代码:
Image img := get_front_img() Number std_dev String prompt = "Input standard deviation. 0=no blurring, 1=minimal blurring, 3=mild blurring, 10=severe blurring" GetNumber(prompt, 3, std_dev) Number time1 = GetCurrentTime() Image blurred_img = img.GaussianBlur(std_dev, std_dev) // 分别设置x、y方向的σ Number time2 = GetCurrentTime() Result(CalcTimeUnitsBetween(time1, time2, 1) + "\n") blurred_img.ShowImage()
2. 手动优化卷积实现(替代方案)
如果必须手动实现,可通过以下两点大幅提升性能:
- 移除无意义的Warp操作:原代码中的Warp是等价映射(
icol * src_img_sx / src_img_sx等于icol),完全多余,直接删除; - 使用小尺寸高斯核:高斯函数的能量集中在3σ范围内,只需生成尺寸为
ceil(6*σ)+1的小核(比如σ=3时用19x19核),再用Convolve()做空间域卷积,避免全尺寸FFT的巨大开销。
优化后的手动实现代码:
Image gaussian_conv_optimized(Image src_img, Number std_dev) { number src_sx, src_sy src_img.GetSize(src_sx, src_sy) // 生成小尺寸高斯核(覆盖3σ范围) Number kernel_size = ceil(6 * std_dev) if (kernel_size % 2 == 0) kernel_size += 1 // 确保奇数尺寸 Number kernel_radius = kernel_size / 2 Image kernel := RealImage("", 4, kernel_size, kernel_size) kernel = exp(-((icol - kernel_radius)**2 + (irow - kernel_radius)**2) / (2 * std_dev**2)) kernel = kernel / Sum(kernel) // 归一化核 // 空间域卷积 Image blurred_img = src_img.Convolve(kernel) return blurred_img } Image img := get_front_img() Number std_dev String prompt = "Input standard deviation. 0=no blurring, 1=minimal blurring, 3=mild blurring, 10=severe blurring" GetNumber(prompt, 3, std_dev) Number time1 = GetCurrentTime() Image blurred_img := gaussian_conv_optimized(img, std_dev) Number time2 = GetCurrentTime() Result(CalcTimeUnitsBetween(time1, time2, 1) + "\n") blurred_img.ShowImage()
问题解答
- 有更优方法:优先使用DM内置的
GaussianBlur()函数,或手动实现小核空间卷积,两者都能大幅提升效率; - 调整算法可实现性能提升:放弃原代码中全尺寸FFT的方案,改用小核卷积或内置函数,处理4K图像的耗时可降低到0.5~1秒区间,接近SciPy的性能。
内容的提问来源于stack exchange,提问作者ChenZX
相关产品推荐
相关产品推荐

