在IDL中使用查找表实现快速角点检测:如何利用查找表提升速度
19998 为本文评分:
3.0
在IDL中使用查找表实现快速角点检测:如何利用查找表提升速度
匿名 2014年1月23日,星期四
在IDL中实现算法通常涉及处理大型数据数组。一种可以加速IDL中某些算法的技术是利用预计算的查找表。这本质上允许绕过计算步骤,代价是增加内存使用。本例实现了FAST角点检测器算法。与许多其他角点检测器算法相比,这是一个简单的算法。每个像素都与围绕该像素形成圆环的16个其他像素进行比较。16个周围像素中的每一个都会被评估为与参考像素相似或不同。最后,如果参考像素至少有N个连续的周围像素被标记为明显更大或明显更小,则该像素被标记为角点。
为了测试速度,我使用以下代码作为参考。
IDL> im=read_image(filepath('ohare.jpg', subdir=['examples','data']))
% Loaded DLM: JPEG.
IDL> im = reform(im[0,*,*])
IDL> tic & x=fast_corner_detector(im) & toc
% Compiled module: FAST_CORNER_DETECTOR.
% Compiled module: ARRAY_INDICES.
% Time elapsed: 42.885000 seconds.
IDL> tic & z=fastcornerfinder(im, threshold=50, n_cont=12) & y=array_indices(z,where(z)) & toc
% Compiled module: FASTCORNERFINDER.
% Time elapsed: 2.6559999 seconds.
IDL> array_equal(x,y)
1
IDL> help, x, y
X LONG = Array[2, 4078]
Y LONG = Array[2, 4078]
在这种情况下,速度比参考代码提高了16倍。这旨在说明一种使IDL代码运行更快的技术。我不保证此实现适用于任何特定目的。代码如下:
;+
; 参考:
; http://www.edwardrosten.com/work/fast.html
;-
function FastCornerFinder, im, threshold=threshold, n_cont=n_cont
compile_opt idl2, logical_predicate
common fast_common, lookup, x_shift, y_shift
; 要查找的连续匹配数
n = n_elements(n_cont) eq 0 ? 9b : byte(n_cont)
if n lt 1 || n gt 16 then message, 'n_cont must be between 1 and 16'
if n_elements(threshold) eq 0 then threshold = 50
if n_elements(lookup) eq 0 then begin
; 一次性公共初始化
; 对于 r = 3,偏移量为
x_shift = [-1, 0, 1, 2, 3, 3, 3, 2, 1, 0,-1,-2,-3,-3,-3,-2]
y_shift = [-3,-3,-3,-2,-1, 0, 1, 2, 3, 3, 3, 2, 1, 0,-1,-2]
; 查找表返回设置的连续位的最大数量,使用位移位(ishft)。
lookup = bytarr(65536)
for i=0, 2^16-1 do begin
x = i or ishft(i, 16)
y = x
for j=0, 15 do begin
if y eq 0 then break
y = x and ishft(y, 1)
endfor
lookup[i] = j
endfor
endif
; 创建一个数组,其中每一位表示圆环上16个位置中的每一个
; 是否与中心显著不同。测试明显更小或更大。
bitsmaller = uintarr(size(im, /dimensions))
bitbigger = uintarr(size(im, /dimensions))
; 确保像素为有符号,以便减法可以为负
fim = fix(im)
; 遍历圆环上的16个位置
for i=0, 15 do begin
bitsmaller or= ishft(1us, i) * ((fim - shift(fim, x_shift[i], y_shift[i])) gt fix(threshold))
bitbigger or= ishft(1us, i) * ((fim - shift(fim, x_shift[i], y_shift[i])) lt -fix(threshold))
endfor
; 使用查找表转换为连续位的数量
return, (lookup[bitsmaller] ge n) or (lookup[bitbigger] ge n)
end