利用im2col提高云检测的速度
常规的“云检测”在计算“滑块”的标准差的时候都是采用双重循环的方式,逐行逐列的进行计算,这样会导致速度很慢。本人提出一种快速计算矩阵“滑块”标准差的方法。
需要读者首先掌握im2col方法:https://blog.csdn.net/luqialiu3392/article/details/105352620
;im2col函数
FUNCTION fun_col2im, column, input_shape, filter_h, filter_w, stride=stride, pad=pad
param_number = N_PARAMS()
IF param_number EQ 4 THEN BEGIN
w= input_shape[0]
h = input_shape[1]
out_h = FLOOR( (h + 2*pad - filter_h) / stride ) + 1
out_w = FLOOR( (w + 2*pad - filter_w) / stride ) + 1
column = REFORM(column, [out_w, out_h, filter_w, filter_h])
; column = TRANSPOSE(column, [2, 3, 0, 1])
img = FLTARR(w + 2*pad + stride - 1, h + 2*pad + stride - 1)
FOR x = 0, filter_w-1 DO BEGIN
x_max = x + stride*out_w
FOR y = 0, filter_h-1 DO BEGIN
y_max = y + stride*out_h
; print, x, x_max, y, y_max
img[x:x_max-1:stride, y:y_max-1:stride] = column[*, *, x, y]
ENDFOR
ENDFOR
end_w = w - 1 + pad
end_h = h - 1 + pad
RETURN, img[pad:end_w, pad:end_h]
ENDIF ELSE BEGIN
PRINT, "Function params is not enough!"
RETURN, 0
ENDELSE
END
PRO im2col
;为了进行模拟,我们根据0.01°的分辨率,创建一个3600*1800的随机数组
input_data = RANDOMN(undefinevar, 3600, 1800)
filter_h = 3
filter_w = 3
stride=1
pad=0
start = SYSTIME(/second)
column = fun_im2col(input_data, filter_h, filter_w, stride=1, pad=0)
out_w = FLOOR( (3600 + 2*pad - filter_h) / stride ) + 1
out_h = FLOOR( (1800 + 2*pad - filter_w) / stride ) + 1
m = STDDEV(column, dimension=2)
m = REFORM(m, [out_w, out_h] )
endtime = SYSTIME(/second)
PRINT,'running time ',endtime-start
END
运行时间为2.2576秒
% Compiled module: TEST.
running time 2.5769999
我们再来看一下采用双重循环的耗时
m = fltarr(3600-2, 1800-2)
start = SYSTIME(/second)
input_data = RANDOMN(undefinevar, 3600, 1800)
FOR x = 0, 3600-3 DO BEGIN
FOR y = 0, 1800-3 DO BEGIN
m[x, y] = stddev( input_data[x:x+2, y:y+2] )
ENDFOR
ENDFOR
endtime = SYSTIME(/second)
PRINT,'running time ',endtime-start
可以看出循环耗时很长, 所以基于im2col方法计算“滑块”标准差或者其他统计量是一种非常快速的方法!
% Compiled module: TEST.
running time 93.859000